diff --git a/ArcFormats/AIRNovel/ArcAIR.cs b/ArcFormats/AIRNovel/ArcAIR.cs new file mode 100644 index 00000000..addbe36c --- /dev/null +++ b/ArcFormats/AIRNovel/ArcAIR.cs @@ -0,0 +1,255 @@ +//! \file ArcAIR.cs +//! \date 2022 Jun 10 +//! \brief AIRNovel engine encrypted resources. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using GameRes.Cryptography; +using GameRes.Formats.PkWare; + +using SharpZip = ICSharpCode.SharpZipLib.Zip; + +namespace GameRes.Formats.AirNovel +{ + internal class AirEntry : ZipEntry + { + public bool IsEncrypted { get; set; } + + public AirEntry (SharpZip.ZipEntry zip_entry) : base (zip_entry) + { + IsEncrypted = Name.EndsWith ("_"); + if (IsEncrypted) + { + Name = Name.Substring (0, Name.Length-1); + Type = FormatCatalog.Instance.GetTypeFromName (Name); + } + } + } + + internal class AirArchive : PkZipArchive + { + public byte[] Key; + public uint CoderLength; + + public AirArchive (ArcView arc, ArchiveFormat impl, ICollection dir, SharpZip.ZipFile native, byte[] key) : base (arc, impl, dir, native) + { + Key = key; + } + } + + [Serializable] + public class AirNovelScheme : ResourceScheme + { + public IDictionary KnownKeys; + } + + [Export(typeof(ArchiveFormat))] + public class AirOpener : ArchiveFormat + { + public override string Tag { get { return "AIR"; } } + public override string Description { get { return "Adobe AIR resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + static readonly ResourceInstance Zip = new ResourceInstance ("ZIP"); + + public override ArcFile TryOpen (ArcView file) + { + if (!file.Name.HasExtension (".air")) + return null; + var input = file.CreateStream(); + SharpZip.ZipFile zip = null; + try + { + SharpZip.ZipStrings.CodePage = Encoding.UTF8.CodePage; + zip = new SharpZip.ZipFile (input); + var files = zip.Cast().Where (z => !z.IsDirectory); + bool has_encrypted = false; + var dir = new List(); + foreach (var f in files) + { + var entry = new AirEntry (f); + has_encrypted |= entry.IsEncrypted; + dir.Add (entry); + } + if (has_encrypted) + { + uint coder_length; + if (FindAirNovelCoderLength (zip, out coder_length)) + { + var key = QueryEncryptionKey (file); + if (!string.IsNullOrEmpty (key)) + { + var rc4_key = AirRc4Crypt.GenerateKey (key); + return new AirArchive (file, this, dir, zip, rc4_key) { CoderLength = coder_length }; + } + } + } + return new PkZipArchive (file, Zip.Value, dir, zip); + } + catch + { + if (zip != null) + zip.Close(); + input.Dispose(); + throw; + } + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var zarc = (AirArchive)arc; + var zent = (AirEntry)entry; + var input = zarc.Native.GetInputStream (zent.NativeEntry); + if (!zent.IsEncrypted) + return input; + var data = new byte[zent.UnpackedSize]; + using (input) + input.Read (data, 0, data.Length); + int enc_len; + if (zent.Name.HasExtension (".an")) + enc_len = data.Length; + else + enc_len = Math.Min (data.Length, (int)zarc.CoderLength); + var rc4 = new AirRc4Crypt (zarc.Key); + rc4.Decrypt (data, 0, enc_len); + return new BinMemoryStream (data, entry.Name); + } + + bool FindAirNovelCoderLength (SharpZip.ZipFile zip, out uint coder_length) + { + coder_length = 0; + var config = zip.GetEntry ("config.anprj"); + if (null == config) + return false; + using (var input = zip.GetInputStream (config)) + { + var coder = FindConfigNode (input, "/config/coder[@len]"); + if (null == coder) + return false; + var lenAttr = coder.Attributes["len"].Value; + var styles = NumberStyles.Integer; + if (lenAttr.StartsWith ("0x")) + { + lenAttr = lenAttr.Substring (2, lenAttr.Length-2); + styles = NumberStyles.HexNumber; + } + return UInt32.TryParse (lenAttr, styles, CultureInfo.InvariantCulture, out coder_length); + } + } + + XmlNode FindConfigNode (Stream input, string xpath) + { + using (var reader = new StreamReader (input)) + { + var xml = new XmlDocument(); + xml.Load (reader); + return xml.DocumentElement.SelectSingleNode (xpath); + } + } + + AirNovelScheme DefaultScheme = new AirNovelScheme { KnownKeys = new Dictionary() }; + + internal IDictionary KnownKeys { get { return DefaultScheme.KnownKeys; } } + + public override ResourceScheme Scheme + { + get { return DefaultScheme; } + set { DefaultScheme = (AirNovelScheme)value; } + } + + string QueryEncryptionKey (ArcView file) + { + var title = FormatCatalog.Instance.LookupGame (file.Name); + if (string.IsNullOrEmpty (title)) + return null; + string key; + if (!KnownKeys.TryGetValue (title, out key)) + return null; + return key; + } + } + + internal class AirRc4Crypt + { + const int KeyLength = 0xFF; + + byte[] KeyState = new byte[KeyLength+1]; + + public AirRc4Crypt (byte[] key) + { + for (int i = 0; i <= KeyLength; ++i) + { + KeyState[i] = (byte)i; + } + int j = 0; + for (int i = 0; i <= KeyLength; ++i) + { + j = (j + KeyState[i] + key[i]) & KeyLength; + KeyState[i] ^= KeyState[j]; + KeyState[j] ^= KeyState[i]; + KeyState[i] ^= KeyState[j]; + } + } + + public static byte[] GenerateKey (string passPhrase) + { + if (string.IsNullOrEmpty (passPhrase)) + throw new ArgumentException ("passPhrase"); + var key = new byte[KeyLength+1]; + for (int i = 0; i < key.Length; ++i) + { + key[i] = (byte)passPhrase[i % passPhrase.Length]; + } + return key; + } + + public void Decrypt (byte[] data, int pos, int length) + { + int i = 0; + int j = 0; + var keyCopy = KeyState.Clone() as byte[]; + int last = Math.Min (pos + length, data.Length); + while (pos < last) + { + i = (i + 1) & KeyLength; + j = (j + keyCopy[i]) & KeyLength; + // i was wondering why standard RC4 encryption class doesn't work here + // well, this swap fails when i == j lol + keyCopy[i] ^= keyCopy[j]; + keyCopy[j] ^= keyCopy[i]; + keyCopy[i] ^= keyCopy[j]; + int k = (keyCopy[i] + keyCopy[j]) & KeyLength; + data[pos++] ^= keyCopy[k]; + } + } + } +} diff --git a/ArcFormats/Abel/ArcFPK.cs b/ArcFormats/Abel/ArcFPK.cs index 1704d468..1066a3d1 100644 --- a/ArcFormats/Abel/ArcFPK.cs +++ b/ArcFormats/Abel/ArcFPK.cs @@ -78,4 +78,9 @@ namespace GameRes.Formats.Abel [ExportMetadata("Extension", "ALP")] [ExportMetadata("Target", "DAT/GENERIC")] public class AlpFormat : ResourceAlias { } + + [Export(typeof(ResourceAlias))] + [ExportMetadata("Extension", "JCP")] + [ExportMetadata("Target", "WAV")] + public class JcpFormat : ResourceAlias { } } diff --git a/ArcFormats/Abel/ImageGPS.cs b/ArcFormats/Abel/ImageGPS.cs index c7989814..4b8ea388 100644 --- a/ArcFormats/Abel/ImageGPS.cs +++ b/ArcFormats/Abel/ImageGPS.cs @@ -24,7 +24,6 @@ // using System; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; using GameRes.Compression; @@ -50,14 +49,16 @@ namespace GameRes.Formats.Abel public GpsFormat () { - Extensions = new string[] { "gps", "cmp" }; + Extensions = new[] { "gps", "gp2", "cmp" }; + Signatures = new[] { 0x535047u, 0x325047u }; // 'GPS', 'GP2' } public override ImageMetaData ReadMetaData (IBinaryStream file) { var header = file.ReadHeader (0x29); + bool is_gp2 = header.AsciiEqual ("GP2"); var gps = new GpsMetaData(); - if (header.ToUInt32 (4) == 0xCCCCCCCC) + if (!is_gp2 && header.ToUInt32 (4) == 0xCCCCCCCC) { gps.HeaderSize = 0x19; gps.Compression = 2; @@ -69,6 +70,8 @@ namespace GameRes.Formats.Abel gps.HeaderSize = 0x29; gps.Compression = header[0x10]; gps.UnpackedSize = header.ToInt32 (0x11); + if (is_gp2) + gps.UnpackedSize = - 1 - gps.UnpackedSize; gps.PackedSize = header.ToInt32 (0x15); gps.Width = header.ToUInt32 (0x19); gps.Height = header.ToUInt32 (0x1D); diff --git a/ArcFormats/Abogado/ArcDSK.cs b/ArcFormats/Abogado/ArcDSK.cs index 23ce1a83..719f3463 100644 --- a/ArcFormats/Abogado/ArcDSK.cs +++ b/ArcFormats/Abogado/ArcDSK.cs @@ -53,6 +53,7 @@ namespace GameRes.Formats.Abogado { "PCM1", "ADP" }, { "PCM2", "ADP" }, { "PCM", "ADP" }, + { "ADPCM", "ADP" }, { "GRAPHIC", "KG" }, { "GRPFILE", "KG" }, { "EFCFILE", "ADP" }, diff --git a/ArcFormats/Adobe/ArcAIR.cs b/ArcFormats/Adobe/ArcAIR.cs new file mode 100644 index 00000000..0e5b129e --- /dev/null +++ b/ArcFormats/Adobe/ArcAIR.cs @@ -0,0 +1,118 @@ +//! \file ArcAIR.cs +//! \date 2023 Aug 22 +//! \brief Adobe AIR resource archive. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.IO.Compression; +using System.Text; + +namespace GameRes.Formats.Adobe +{ + [Export(typeof(ArchiveFormat))] + public class DatOpener : ArchiveFormat + { + public override string Tag { get => "DAT/AIR"; } + public override string Description { get => "Adobe AIR resource archive"; } + public override uint Signature { get => 0; } + public override bool IsHierarchic { get => false; } + public override bool CanWrite { get => false; } + + public override ArcFile TryOpen (ArcView file) + { + uint index_pos = Binary.BigEndian (file.View.ReadUInt32 (0)); + if (index_pos >= file.MaxOffset || 0 == index_pos || file.MaxOffset > 0x40000000) + return null; + uint index_size = (uint)(file.MaxOffset - index_pos); + if (index_size > 0x100000) // arbitrary max size for compressed index + return null; + using (var input = file.CreateStream (index_pos, index_size)) + using (var unpacked = new DeflateStream (input, CompressionMode.Decompress)) + using (var index = new BinaryStream (unpacked, file.Name)) + { + if (0x0A != index.ReadUInt8() || + 0x0B != index.ReadUInt8() || + 0x01 != index.ReadUInt8()) + return null; + var name_buffer = new byte[0x80]; + var dir = new List(); + while (index.PeekByte() != -1) + { + int length = index.ReadUInt8(); + if (0 == (length & 1)) + return null; + length >>= 1; + if (0 == length) + break; + index.Read (name_buffer, 0, length); + var name = Encoding.UTF8.GetString (name_buffer, 0, length); + if (0x09 != index.ReadUInt8() || + 0x05 != index.ReadUInt8() || + 0x01 != index.ReadUInt8()) + return null; + if (0x04 != index.ReadUInt8()) // invalid number signature + return null; + uint offset = ReadInteger (index); + if (0x04 != index.ReadUInt8()) + return null; + uint size = ReadInteger (index); + var entry = Create (name); + entry.Offset = offset; + entry.Size = size; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + return new ArcFile (file, this, dir); + } + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + if (0 == entry.Size) + return Stream.Null; + var input = arc.File.CreateStream (entry.Offset, entry.Size); + return new DeflateStream (input, CompressionMode.Decompress); + } + + internal static uint ReadInteger (IBinaryStream input) + { + uint u = input.ReadUInt8(); + if (u < 0x80) + return u; + u = (u & 0x7F) << 7; + uint b = input.ReadUInt8(); + if (b < 0x80) + return u | b; + u = (u | b & 0x7F) << 7; + b = input.ReadUInt8(); + if (b < 0x80) + return u | b; + u = (u | b & 0x7F) << 8; + return u | input.ReadUInt8(); + } + } +} diff --git a/ArcFormats/AliceSoft/ArcAFA.cs b/ArcFormats/AliceSoft/ArcAFA.cs index 53c08fc3..2d2975f3 100644 --- a/ArcFormats/AliceSoft/ArcAFA.cs +++ b/ArcFormats/AliceSoft/ArcAFA.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; +using System.Text; using GameRes.Compression; namespace GameRes.Formats.AliceSoft @@ -40,6 +41,16 @@ namespace GameRes.Formats.AliceSoft public override bool IsHierarchic { get { return true; } } public override bool CanWrite { get { return false; } } + public AfaOpener () + { + ContainedFormats = new[] { "QNT", "AJP", "DCF", "OGG" }; + Settings = new[] { AfaEncoding }; + } + + internal readonly EncodingSetting AfaEncoding = new EncodingSetting ("AFAEncodingCP", "DefaultEncoding"); + + internal Encoding NameEncoding { get { return AfaEncoding.Get(); } } + public override ArcFile TryOpen (ArcView file) { if (!file.View.AsciiEqual (8, "AlicArch")) @@ -54,6 +65,7 @@ namespace GameRes.Formats.AliceSoft if (!IsSaneCount (count)) return null; + var default_enc = NameEncoding; var dir = new List (count); var name_buf = new byte[0x40]; using (var input = file.CreateStream (0x2C, packed_size)) @@ -70,7 +82,7 @@ namespace GameRes.Formats.AliceSoft name_buf = new byte[index_step]; if (index_step != index.Read (name_buf, 0, index_step)) return null; - var name = Encodings.cp932.GetString (name_buf, 0, name_length); + var name = default_enc.GetString (name_buf, 0, name_length); var entry = FormatCatalog.Instance.Create (name); index.ReadInt32(); index.ReadInt32(); diff --git a/ArcFormats/AliceSoft/ImageDCF.cs b/ArcFormats/AliceSoft/ImageDCF.cs index 982ae20b..587aa56c 100644 --- a/ArcFormats/AliceSoft/ImageDCF.cs +++ b/ArcFormats/AliceSoft/ImageDCF.cs @@ -2,7 +2,7 @@ //! \date Fri Jul 29 14:07:15 2016 //! \brief AliceSoft incremental image format. // -// Copyright (C) 2016-2018 by morkt +// Copyright (C) 2016-2022 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -27,6 +27,7 @@ using System; using System.ComponentModel.Composition; using System.Diagnostics; using System.IO; +using System.Text; using System.Windows.Media; using GameRes.Compression; using GameRes.Utility; @@ -37,6 +38,15 @@ namespace GameRes.Formats.AliceSoft { public string BaseName; public long DataOffset; + public bool IsPcf; + } + + internal interface IBaseImageReader + { + int BPP { get; } + byte[] Data { get; } + + void Unpack (); } [Export(typeof(ImageFormat))] @@ -46,17 +56,25 @@ namespace GameRes.Formats.AliceSoft public override string Description { get { return "AliceSoft System incremental image"; } } public override uint Signature { get { return 0x20666364; } } // 'dcf ' + public DcfFormat () + { + Extensions = new[] { "dcf", "pcf" }; + Signatures = new[] { 0x20666364u, 0x20666370u }; + } + + static readonly ResourceInstance Afa = new ResourceInstance ("AFA"); + public override ImageMetaData ReadMetaData (IBinaryStream stream) { - stream.Seek (4, SeekOrigin.Current); - uint header_size = stream.ReadUInt32(); - long data_pos = stream.Position + header_size; - if (stream.ReadInt32() != 1) + var header = stream.ReadHeader (0x1C); + uint header_size = header.ToUInt32 (4); + long data_pos = 8 + header_size; + if (header.ToInt32 (8) != 1) return null; - uint width = stream.ReadUInt32(); - uint height = stream.ReadUInt32(); - int bpp = stream.ReadInt32(); - int name_length = stream.ReadInt32(); + uint width = header.ToUInt32 (0x0C); + uint height = header.ToUInt32 (0x10); + int bpp = header.ToInt32 (0x14); + int name_length = header.ToInt32 (0x18); if (name_length <= 0) return null; int shift = (name_length % 7) + 1; @@ -70,18 +88,17 @@ namespace GameRes.Formats.AliceSoft Width = width, Height = height, BPP = bpp, - BaseName = Encodings.cp932.GetString (name_bits), + BaseName = Afa.Value.NameEncoding.GetString (name_bits), DataOffset = data_pos, + IsPcf = stream.Signature == 0x20666370u, }; } public override ImageData Read (IBinaryStream stream, ImageMetaData info) { - using (var reader = new DcfReader (stream, (DcfMetaData)info)) - { - reader.Unpack(); - return ImageData.Create (info, reader.Format, null, reader.Data, reader.Stride); - } + var reader = new DcfReader (stream, (DcfMetaData)info); + reader.Unpack(); + return ImageData.Create (reader.Info, reader.Format, null, reader.Data, reader.Stride); } public override void Write (Stream file, ImageData image) @@ -90,7 +107,7 @@ namespace GameRes.Formats.AliceSoft } } - internal sealed class DcfReader : IDisposable + internal sealed class DcfReader : IBaseImageReader { IBinaryStream m_input; DcfMetaData m_info; @@ -100,10 +117,14 @@ namespace GameRes.Formats.AliceSoft int m_overlay_bpp; int m_base_bpp; - static readonly Lazy s_QntFormat = new Lazy (() => ImageFormat.FindByTag ("QNT")); + static readonly ResourceInstance s_QntFormat = new ResourceInstance ("QNT"); + static readonly ResourceInstance s_DcfFormat = new ResourceInstance ("DCF"); internal ImageFormat Qnt { get { return s_QntFormat.Value; } } + internal ImageFormat Dcf { get { return s_DcfFormat.Value; } } + public int BPP { get { return m_base_bpp; } } + public ImageMetaData Info { get; private set; } public byte[] Data { get { return m_output; } } public PixelFormat Format { get; private set; } public int Stride { get; private set; } @@ -112,10 +133,13 @@ namespace GameRes.Formats.AliceSoft { m_input = input; m_info = info; + Info = info; } public void Unpack () { + int pt_x = 0; + int pt_y = 0; long next_pos = m_info.DataOffset; for (;;) { @@ -131,7 +155,12 @@ namespace GameRes.Formats.AliceSoft using (var input = new ZLibStream (m_input.AsStream, CompressionMode.Decompress, true)) input.Read (m_mask, 0, unpacked_size); } - else if (0x64676364 == id) // 'dcgd' + else if (0x6C647470 == id) // 'ptdl' + { + pt_x = m_input.ReadInt32(); + pt_y = m_input.ReadInt32(); + } + else if (0x64676364 == id || 0x64676370 == id) // 'dcgd' || 'pcgd' break; } long qnt_pos = m_input.Position; @@ -147,18 +176,28 @@ namespace GameRes.Formats.AliceSoft var overlay = new QntFormat.Reader (reg, qnt_info); overlay.Unpack(); m_overlay_bpp = overlay.BPP; - if (m_mask != null) + if (m_mask != null || m_info.IsPcf) ReadBaseImage(); - if (m_base != null) + if (m_info.IsPcf) { - m_output = ApplyOverlay (overlay.Data); - SetFormat ((int)m_info.Width, m_overlay_bpp); + if (null == m_base) + SetEmptyBase(); + qnt_info.OffsetX = pt_x; + qnt_info.OffsetY = pt_y; + BlendOverlay (qnt_info, overlay.Data); + m_output = m_base; + SetFormat (m_info.iWidth, m_base_bpp); + } + else if (m_base != null) + { + m_output = MaskOverlay (overlay.Data); + SetFormat (m_info.iWidth, m_overlay_bpp); } else { m_output = overlay.Data; - SetFormat ((int)qnt_info.Width, m_overlay_bpp); + SetFormat (qnt_info.iWidth, m_overlay_bpp); } } } @@ -169,14 +208,20 @@ namespace GameRes.Formats.AliceSoft Stride = width * (bpp / 8); } - byte[] ApplyOverlay (byte[] overlay) + void SetEmptyBase () { - int blocks_x = (int)m_info.Width / 0x10; - int blocks_y = (int)m_info.Height / 0x10; + m_base_bpp = 32; + m_base = new byte[m_info.Width * m_info.Height * 4]; + } + + byte[] MaskOverlay (byte[] overlay) + { + int blocks_x = m_info.iWidth / 0x10; + int blocks_y = m_info.iHeight / 0x10; int base_step = m_base_bpp / 8; int overlay_step = m_overlay_bpp / 8; - int base_stride = (int)m_info.Width * base_step; - int overlay_stride = (int)m_info.Width * overlay_step; + int base_stride = m_info.iWidth * base_step; + int overlay_stride = m_info.iWidth * overlay_step; int mask_pos = 4; for (int y = 0; y < blocks_y; ++y) { @@ -208,6 +253,58 @@ namespace GameRes.Formats.AliceSoft return overlay; } + void BlendOverlay (ImageMetaData overlay_info, byte[] overlay) + { + int ovl_x = overlay_info.OffsetX; + int ovl_y = overlay_info.OffsetY; + int ovl_width = overlay_info.iWidth; + int ovl_height = overlay_info.iHeight; + int base_width = m_info.iWidth; + int base_height = m_info.iHeight; + if (checked(ovl_x + ovl_width) > base_width) + ovl_width = base_width - ovl_x; + if (checked(ovl_y + ovl_height) > base_height) + ovl_height = base_height - ovl_y; + if (ovl_height <= 0 || ovl_width <= 0) + return; + + int dst_stride = m_info.iWidth * 4; + int src_stride = overlay_info.iWidth * 4; + int dst = ovl_y * dst_stride + ovl_x * 4; + int src = 0; + int gap = dst_stride - src_stride; + for (int y = 0; y < overlay_info.iHeight; ++y) + { + for (int x = 0; x < overlay_info.iWidth; ++x) + { + byte src_alpha = overlay[src+3]; + if (src_alpha != 0) + { + if (0xFF == src_alpha || 0 == m_base[dst+3]) + { + m_base[dst] = overlay[src]; + m_base[dst+1] = overlay[src+1]; + m_base[dst+2] = overlay[src+2]; + m_base[dst+3] = src_alpha; + } + else + { + m_base[dst+0] = (byte)((overlay[src+0] * src_alpha + + m_base[dst+0] * (0xFF - src_alpha)) / 0xFF); + m_base[dst+1] = (byte)((overlay[src+1] * src_alpha + + m_base[dst+1] * (0xFF - src_alpha)) / 0xFF); + m_base[dst+2] = (byte)((overlay[src+2] * src_alpha + + m_base[dst+2] * (0xFF - src_alpha)) / 0xFF); + m_base[dst+3] = (byte)Math.Max (src_alpha, m_base[dst+3]); + } + } + dst += 4; + src += 4; + } + dst += gap; + } + } + void ReadBaseImage () { try @@ -215,13 +312,29 @@ namespace GameRes.Formats.AliceSoft string dir_name = VFS.GetDirectoryName (m_info.FileName); string base_name = Path.ChangeExtension (m_info.BaseName, "qnt"); base_name = VFS.CombinePath (dir_name, base_name); + ImageFormat base_format = null; + Func create_reader; + if (VFS.FileExists (base_name)) + { + base_format = Qnt; + create_reader = (s, m) => new QntFormat.Reader (s.AsStream, (QntMetaData)m); + } + else + { + base_name = Path.ChangeExtension (m_info.BaseName, "pcf"); + if (VFS.IsPathEqualsToFileName (m_info.FileName, base_name)) + return; + base_name = VFS.CombinePath (dir_name, base_name); + base_format = Dcf; + create_reader = (s, m) => new DcfReader (s, (DcfMetaData)m); + } using (var base_file = VFS.OpenBinaryStream (base_name)) { - var base_info = Qnt.ReadMetaData (base_file) as QntMetaData; + var base_info = base_format.ReadMetaData (base_file); if (null != base_info && m_info.Width == base_info.Width && m_info.Height == base_info.Height) { base_info.FileName = base_name; - var reader = new QntFormat.Reader (base_file.AsStream, base_info); + var reader = create_reader (base_file, base_info); reader.Unpack(); m_base_bpp = reader.BPP; m_base = reader.Data; @@ -233,11 +346,5 @@ namespace GameRes.Formats.AliceSoft Trace.WriteLine (X.Message, "[DCF]"); } } - - #region IDisposable Members - public void Dispose () - { - } - #endregion } } diff --git a/ArcFormats/AliceSoft/ImageQNT.cs b/ArcFormats/AliceSoft/ImageQNT.cs index 85f8ca09..ed1ebd00 100644 --- a/ArcFormats/AliceSoft/ImageQNT.cs +++ b/ArcFormats/AliceSoft/ImageQNT.cs @@ -97,7 +97,7 @@ namespace GameRes.Formats.AliceSoft return ImageData.Create (info, format, null, reader.Data, stride); } - internal class Reader + internal class Reader : IBaseImageReader { byte[] m_input; byte[] m_alpha; diff --git a/ArcFormats/Amaterasu/ArcAMI.cs b/ArcFormats/Amaterasu/ArcAMI.cs index 197a3925..bc7e8d0b 100644 --- a/ArcFormats/Amaterasu/ArcAMI.cs +++ b/ArcFormats/Amaterasu/ArcAMI.cs @@ -339,7 +339,7 @@ namespace GameRes.Formats.Amaterasu } [Export(typeof(ScriptFormat))] - public class ScrFormat : ScriptFormat + public class ScrFormat : GenericScriptFormat { public override string Tag { get { return "SCR/AMI"; } } public override string Description { get { return Strings.arcStrings.SCRDescription; } } diff --git a/ArcFormats/Apricot/ArcDAT.cs b/ArcFormats/Apricot/ArcDAT.cs index 3d7e1485..5b0ec9da 100644 --- a/ArcFormats/Apricot/ArcDAT.cs +++ b/ArcFormats/Apricot/ArcDAT.cs @@ -83,126 +83,33 @@ namespace GameRes.Formats.Apricot dir.Add (entry); } } - return new Mpf2Archive (file, this, dir, arc_list); + var parts = new List (arc_list.Count); + try + { + foreach (var arc_entry in arc_list) + { + var arc_file = VFS.OpenView (arc_entry); + parts.Add (arc_file); + } + } + catch + { + foreach (var part in parts) + part.Dispose(); + throw; + } + return new MultiFileArchive (file, this, dir, parts); } } public override Stream OpenEntry (ArcFile arc, Entry entry) { - var mpf = (Mpf2Archive)arc; - var input = mpf.ViewChain.CreateStream (entry.Offset, entry.Size); + var mpf = (MultiFileArchive)arc; + var input = mpf.OpenStream (entry); var pent = entry as PackedEntry; if (pent != null && pent.IsPacked) input = new ZLibStream (input, CompressionMode.Decompress); return input; } } - - internal class Mpf2Archive : ArcFile - { - ArcViewChain m_parts; - - public ArcViewChain ViewChain { get { return m_parts; } } - - public Mpf2Archive (ArcView arc, ArchiveFormat impl, ICollection dir, IReadOnlyList arc_list) - : base (arc, impl, dir) - { - m_parts = new ArcViewChain (arc, arc_list); - } - - bool m_disposed = false; - protected override void Dispose (bool disposing) - { - if (disposing && !m_disposed) - { - if (m_parts != null) - m_parts.Dispose(); - m_disposed = true; - } - } - } - - internal sealed class ArcViewChain : IDisposable - { - ArcView m_file; - IReadOnlyList m_parts; - - public IEnumerable Parts { - get { - yield return m_file; - if (m_parts != null) - foreach (var part in m_parts) - yield return part; - } - } - - public ArcViewChain (ArcView file, IReadOnlyList arc_list) - { - var parts = new List (arc_list.Count); - try - { - foreach (var arc_entry in arc_list) - { - var arc_file = VFS.OpenView (arc_entry); - parts.Add (arc_file); - } - } - catch - { - foreach (var part in parts) - part.Dispose(); - throw; - } - m_file = file; - m_parts = parts; - } - - public Stream CreateStream (long offset, uint size) - { - Stream input = null; - try - { - long part_offset = 0; - long entry_start = offset; - long entry_end = offset + size; - foreach (var part in Parts) - { - long part_end_offset = part_offset + part.MaxOffset; - if (entry_start < part_end_offset) - { - uint part_size = (uint)Math.Min (entry_end - entry_start, part_end_offset - entry_start); - var entry_part = part.CreateStream (entry_start - part_offset, part_size); - if (input != null) - input = new ConcatStream (input, entry_part); - else - input = entry_part; - entry_start += part_size; - if (entry_start >= entry_end) - break; - } - part_offset = part_end_offset; - } - return input ?? Stream.Null; - } - catch - { - if (input != null) - input.Dispose(); - throw; - } - } - - bool m_disposed = false; - public void Dispose () - { - if (m_disposed) - return; - if (m_parts != null) - { - foreach (var arc in m_parts) - arc.Dispose(); - } - m_disposed = true; - } - } } diff --git a/ArcFormats/ArcCommon.cs b/ArcFormats/ArcCommon.cs index fbf0c37b..22b823f5 100644 --- a/ArcFormats/ArcCommon.cs +++ b/ArcFormats/ArcCommon.cs @@ -350,4 +350,10 @@ namespace GameRes.Formats public override string Description { get { return "Unidentified data file"; } } public override uint Signature { get { return 0; } } } + + // [970725][Guilty] Onii-chan e + [Export(typeof(ResourceAlias))] + [ExportMetadata("Extension", "GLT")] + [ExportMetadata("Target", "BMP")] + public class GltFormat : ResourceAlias { } } diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 8061dfd8..abb23ea5 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -98,15 +98,22 @@ + + + + + + + @@ -130,6 +137,12 @@ + + + + + + @@ -251,6 +264,9 @@ + + + @@ -335,6 +351,8 @@ + + @@ -744,7 +762,7 @@ - + @@ -824,6 +842,7 @@ + @@ -832,6 +851,7 @@ + diff --git a/ArcFormats/BellDa/ArcDAT.cs b/ArcFormats/BellDa/ArcDAT.cs index 55403518..de69b0c3 100644 --- a/ArcFormats/BellDa/ArcDAT.cs +++ b/ArcFormats/BellDa/ArcDAT.cs @@ -27,11 +27,13 @@ using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; using GameRes.Compression; +using GameRes.Formats.Maika; +using GameRes.Utility; namespace GameRes.Formats.BellDa { [Export(typeof(ArchiveFormat))] - public sealed class BldOpener : ArchiveFormat + public sealed class BldOpener : Mk2Opener { public override string Tag { get { return "DAT/BLD"; } } public override string Description { get { return "BELL-DA resource archive"; } } @@ -39,6 +41,13 @@ namespace GameRes.Formats.BellDa public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } + public BldOpener () + { + Signatures = new[] { this.Signature }; + Settings = null; + Scheme = null; + } + public override ArcFile TryOpen (ArcView file) { var version_str = file.View.ReadString (4, 4).TrimEnd ('\x1A'); @@ -66,26 +75,5 @@ namespace GameRes.Formats.BellDa } return new ArcFile (file, this, dir); } - - public override Stream OpenEntry (ArcFile arc, Entry entry) - { - // XXX compression method identical to Maika.Mk2Opener - var pent = (PackedEntry)entry; - if (null == pent || !pent.IsPacked) - { - var id_str = arc.File.View.ReadString (entry.Offset, 2); - if (id_str != "B1" && id_str != "C1" && id_str != "D1" && id_str != "E1") - return base.OpenEntry (arc, entry); - uint packed_size = arc.File.View.ReadUInt32 (entry.Offset+2); - if (packed_size != entry.Size - 10) - return base.OpenEntry (arc, entry); - pent.Size = packed_size; - pent.UnpackedSize = arc.File.View.ReadUInt32 (entry.Offset+6); - pent.Offset += 10; - pent.IsPacked = true; - } - var input = arc.File.CreateStream (entry.Offset, entry.Size); - return new LzssStream (input); - } } } diff --git a/ArcFormats/Cadath/ImageKGF.cs b/ArcFormats/Cadath/ImageKGF.cs index 877cb656..7e161570 100644 --- a/ArcFormats/Cadath/ImageKGF.cs +++ b/ArcFormats/Cadath/ImageKGF.cs @@ -136,14 +136,18 @@ namespace GameRes.Formats.Cadath if (0 != (bits[i >> 3] & 1)) { byte v = m_input.ReadUInt8(); - int count = m_input.ReadUInt8() + 3; + int count = Math.Min (m_input.ReadUInt8() + 3, data.Length - dst); for (int j = 0; j < count; ++j) + { data[dst++] = v; + } } else { data[dst++] = m_input.ReadUInt8(); } + if (dst >= data.Length) + break; bits[i >> 3] >>= 1; } CopyChannels (data); diff --git a/ArcFormats/ClickTeam/ArcMF.cs b/ArcFormats/ClickTeam/ArcMF.cs new file mode 100644 index 00000000..71764e2b --- /dev/null +++ b/ArcFormats/ClickTeam/ArcMF.cs @@ -0,0 +1,100 @@ +//! \file ArcMF.cs +//! \date 2023 Aug 09 +//! \brief Multimedia Fusion archive. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Compression; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Text; + +namespace GameRes.Formats.ClickTeam +{ + [Export(typeof(ArchiveFormat))] + public class MfOpener : ArchiveFormat + { + public override string Tag { get { return "MFS"; } } + public override string Description { get { return "Multimedia Fusion resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + public MfOpener () + { + Signatures = new uint[] { 0x77777777, 0 }; // 'wwww' + Extensions = new string[] { "" }; + } + + static readonly byte[] s_mfs_header = { + (byte)'w', (byte)'w', (byte)'w', (byte)'w', 0x49, 0x87, 0x47, 0x12, + }; + + public override ArcFile TryOpen (ArcView file) + { + long base_offset = 0; + if (0x5A4D == file.View.ReadUInt16 (0)) // 'MZ' + { + var exe = new ExeFile (file); + base_offset = exe.Overlay.Offset; + } + if (base_offset + 0x20 > file.MaxOffset || !file.View.BytesEqual (base_offset, s_mfs_header)) + return null; + + int count = file.View.ReadInt32 (base_offset + 0x1C); + if (!IsSaneCount (count)) + return null; + + long index_pos = base_offset + 0x20; + var dir = new List (count); + var name_buffer = new byte[520]; + for (int i = 0; i < count; ++i) + { + int name_length = file.View.ReadUInt16 (index_pos) * 2; + if (name_length > name_buffer.Length) + return null; + file.View.Read (index_pos + 2, name_buffer, 0, (uint)name_length); + var name = Encoding.Unicode.GetString (name_buffer, 0, name_length); + index_pos += 2 + name_length; + var entry = Create (name); + entry.IsPacked = name != "mmfs2.dll"; + entry.Size = file.View.ReadUInt32 (index_pos + 4); + entry.Offset = index_pos + 8; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + index_pos = entry.Offset + entry.Size; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pent = (PackedEntry)entry; + Stream input = arc.File.CreateStream (entry.Offset, entry.Size); + if (pent.IsPacked) + input = new ZLibStream (input, CompressionMode.Decompress); + return input; + } + } +} diff --git a/ArcFormats/Cmvs/ArcCPZ.cs b/ArcFormats/Cmvs/ArcCPZ.cs index 365210a5..a1d3dd61 100644 --- a/ArcFormats/Cmvs/ArcCPZ.cs +++ b/ArcFormats/Cmvs/ArcCPZ.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; using System.Linq; +using GameRes.Formats.Cmvs; using GameRes.Utility; namespace GameRes.Formats.Purple @@ -133,18 +134,38 @@ namespace GameRes.Formats.Purple var index_copy = new CowArray (index, 0, file_table_size).ToArray(); var cmvs_md5 = cpz.CmvsMd5.Clone() as uint[]; - foreach (var scheme in KnownSchemes.Values.Where (s => s.Version == cpz.Version)) + var scheme = CreateCpz5Scheme(Md5Variant.Mirai); +// foreach (var scheme in KnownSchemes.Values.Where (s => s.Version == cpz.Version)) { var arc = ReadIndex (file, scheme, cpz, index, arc_key); if (null != arc) return arc; // both CmvsMd5 and index was altered by ReadIndex in decryption attempt Array.Copy (cmvs_md5, cpz.CmvsMd5, 4); - Array.Copy (index, index_copy, file_table_size); + Array.Copy (index_copy, index, file_table_size); } throw new UnknownEncryptionScheme(); } + static uint[] DefaultCpz5Secret = { + 0xCD90F089, 0xE982B782, 0xA282AB88, 0xCD82718E, 0x52838A83, 0xA882AA82, 0x7592648E, 0xB582AB82, + 0xE182BF82, 0xDC82A282, 0x4281B782, 0xED82F48E, 0xBF82EA82, 0xA282E182, 0xB782DC82, 0x6081E682, + 0xC6824181, 0xA482A282, 0xE082A982, 0xF48EA482, 0xBF82C182, 0xA282E182, 0xB582DC82, 0xF481BD82, + }; + + static CmvsScheme CreateCpz5Scheme(Md5Variant md5) + { + return new CmvsScheme + { + Version = 5, + Cpz5Secret = DefaultCpz5Secret, + Md5Variant = md5, + DecoderFactor = 0x1A743125, + EntryInitKey = 0x2547A39E, + EntryTailKey = 0xBC, + }; + } + internal ArcFile ReadIndex (ArcView file, CmvsScheme scheme, CpzHeader cpz, byte[] index, ArchiveKey arc_key) { var cmvs_md5 = Cmvs.MD5.Create (scheme.Md5Variant); diff --git a/ArcFormats/Cmvs/CmvsMD5.cs b/ArcFormats/Cmvs/CmvsMD5.cs index e68e7fea..77604e34 100644 --- a/ArcFormats/Cmvs/CmvsMD5.cs +++ b/ArcFormats/Cmvs/CmvsMD5.cs @@ -27,7 +27,7 @@ using GameRes.Utility; namespace GameRes.Formats.Cmvs { - public enum Md5Variant { A, B, Chrono, Memoria, Natsu, Aoi } + public enum Md5Variant { A, B, Chrono, Memoria, Natsu, Aoi, Mirai } public abstract class MD5 : Cryptography.MD5Base { @@ -46,6 +46,7 @@ namespace GameRes.Formats.Cmvs case Md5Variant.Memoria: return new Md5Memoria(); case Md5Variant.Natsu: return new Md5Natsu(); case Md5Variant.Aoi: return new Md5Aoi(); + case Md5Variant.Mirai: return new Md5Mirai(); default: throw new System.ArgumentException ("Unknown MD5 variant", "variant"); } } @@ -153,6 +154,25 @@ namespace GameRes.Formats.Cmvs } } + public class Md5Mirai : MD5 + { + protected override void InitState () + { + m_state[0] = 0x67452301; + m_state[1] = 0xEFCDAB89; + m_state[2] = 0x98BADCFE; + m_state[3] = 0x10325476; + } + + protected override void SetResult (uint[] data) + { + data[0] = m_state[0]; + data[1] = m_state[1]; + data[2] = m_state[2]; + data[3] = m_state[3]; + } + } + public class Md5Aoi : MD5 { protected override void InitState () diff --git a/ArcFormats/DraftArc.cs b/ArcFormats/DraftArc.cs index f658fe9a..ea9c0f0d 100644 --- a/ArcFormats/DraftArc.cs +++ b/ArcFormats/DraftArc.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2022 by morkt +// Copyright (C) 2023 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -29,11 +29,11 @@ namespace GameRes.Formats.?????? [Export(typeof(ArchiveFormat))] public class PakOpener : ArchiveFormat { - public override string Tag { get { return "ARC"; } } - public override string Description { get { return "?????? engine resource archive"; } } - public override uint Signature { get { return 0; } } - public override bool IsHierarchic { get { return false; } } - public override bool CanWrite { get { return false; } } + public override string Tag { get => "ARC"; } + public override string Description { get => "?????? engine resource archive"; } + public override uint Signature { get => 0; } + public override bool IsHierarchic { get => false; } + public override bool CanWrite { get => false; } public override ArcFile TryOpen (ArcView file) { diff --git a/ArcFormats/DraftAudio.cs b/ArcFormats/DraftAudio.cs index a083c247..b0f1cbc6 100644 --- a/ArcFormats/DraftAudio.cs +++ b/ArcFormats/DraftAudio.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2022 by morkt +// Copyright (C) 2023 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -26,10 +26,10 @@ namespace GameRes.Formats.?????? [Export(typeof(AudioFormat))] public class xxxAudio : AudioFormat { - public override string Tag { get { return "xxx"; } } - public override string Description { get { return "?????? audio resource"; } } - public override uint Signature { get { return 0; } } - public override bool CanWrite { get { return false; } } + public override string Tag { get => "xxx"; } + public override string Description { get => "?????? audio resource"; } + public override uint Signature { get => 0; } + public override bool CanWrite { get => false; } public override SoundInput TryOpen (IBinaryStream file) { diff --git a/ArcFormats/DraftImage.cs b/ArcFormats/DraftImage.cs index ddf72596..6124a62d 100644 --- a/ArcFormats/DraftImage.cs +++ b/ArcFormats/DraftImage.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2022 by morkt +// Copyright (C) 2023 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -28,9 +28,9 @@ namespace GameRes.Formats.?????? [Export(typeof(ImageFormat))] public class xxxFormat : ImageFormat { - public override string Tag { get { return "xxx"; } } - public override string Description { get { return "?????? image format"; } } - public override uint Signature { get { return 0; } } + public override string Tag { get => "xxx"; } + public override string Description { get => "?????? image format"; } + public override uint Signature { get => 0; } public override ImageMetaData ReadMetaData (IBinaryStream file) { diff --git a/ArcFormats/DxLib/ArcDX8.cs b/ArcFormats/DxLib/ArcDX8.cs new file mode 100644 index 00000000..edc05b80 --- /dev/null +++ b/ArcFormats/DxLib/ArcDX8.cs @@ -0,0 +1,70 @@ +//! \file ArcDX8.cs +//! \date 2022 Jun 05 +//! \brief DxLib archive version 8. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.DxLib +{ + [Export(typeof(ArchiveFormat))] + public class Dx8Opener : DxOpener + { + public override string Tag { get { return "BIN/DXLIB"; } } + public override string Description { get { return "DxLib archive version 8"; } } + public override uint Signature { get { return 0x00085844; } } + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + public Dx8Opener () + { + Extensions = new[] { "bin" }; + Signatures = new[] { 0x00085844u }; + } + + static readonly byte[] DefaultKey = new byte[] { 0xBE, 0xC8, 0x8A, 0xF5, 0x28, 0x50, 0xC9 }; + + public override ArcFile TryOpen (ArcView file) + { + var dx = new DxHeader { + IndexSize = file.View.ReadUInt32 (4), + BaseOffset = file.View.ReadInt64 (8), + IndexOffset = file.View.ReadInt64 (0x10), + FileTable = (uint)file.View.ReadInt64 (0x18), + DirTable = (uint)file.View.ReadInt64 (0x20), + CodePage = file.View.ReadInt32 (0x28), + }; + if (dx.DirTable >= dx.IndexSize || dx.FileTable >= dx.IndexSize) + return null; + var key = DefaultKey; + var index = file.View.ReadBytes (dx.IndexOffset, dx.IndexSize); + Decrypt (index, 0, index.Length, 0, key); + // decrypt-2 + // decompress + return null; + } + } +} diff --git a/ArcFormats/Emote/ArcPSB.cs b/ArcFormats/Emote/ArcPSB.cs index 590b3812..a82eac0a 100644 --- a/ArcFormats/Emote/ArcPSB.cs +++ b/ArcFormats/Emote/ArcPSB.cs @@ -148,7 +148,7 @@ namespace GameRes.Formats.Emote ImageFormat TlgFormat { get { return s_TlgFormat.Value; } } - static Lazy s_TlgFormat = new Lazy (() => ImageFormat.FindByTag ("TLG")); + static ResourceInstance s_TlgFormat = new ResourceInstance ("TLG"); } /// diff --git a/ArcFormats/Entis/EriReader.cs b/ArcFormats/Entis/EriReader.cs index 5bd91a48..63100ad0 100644 --- a/ArcFormats/Entis/EriReader.cs +++ b/ArcFormats/Entis/EriReader.cs @@ -56,6 +56,7 @@ namespace GameRes.Formats.Entis float[] m_ptrMatrixBuf; float[] m_ptrIQParamBuf; byte[] m_ptrIQParamTable; +// float[] m_ptrBuffer2; sbyte[] m_ptrBlockLineBuf; sbyte[] m_ptrNextBlockBuf; @@ -769,6 +770,7 @@ namespace GameRes.Formats.Entis { throw new NotImplementedException(); /* + if (m_nChannelCount < 3) throw new InvalidFormatException(); m_nDstPixelBytes = m_info.BPP >> 3; @@ -1137,6 +1139,42 @@ namespace GameRes.Formats.Entis } } + void LossyRestoreRGB24_V9 () + { + /* + int nLineOffset = 0; + int nBytesPerPixel = m_nDstPixelBytes; + int ptrDstLine = m_ptrDstBlock; + + for (uint y = 0; y < m_nDstHeight; ++y) + { + int nOffsetPos = nLineOffset; + int ptrNextDst = ptrDstLine; + + for (uint x = 0; x < m_nDstWidth; ++x) + { + m_output[ptrNextDst ] = RoundR32ToByte (m_ptrBuffer2[0][nOffsetPos]); + m_output[ptrNextDst+1] = RoundR32ToByte (m_ptrBuffer2[1][nOffsetPos]); + m_output[ptrNextDst+2] = RoundR32ToByte (m_ptrBuffer2[2][nOffsetPos]); + ++nOffsetPos; + ptrNextDst += nBytesPerPixel; + } + nLineOffset += m_nBlockSize; + ptrDstLine += m_nDstLineBytes; + } + */ + } + + static byte RoundR32ToByte (float r) + { + int n = Erisa.RoundR32ToInt (r); + if (n < 0) + return 0; + else if (n >= 0x100) + return 0xFF; + return (byte)n; + } + void RestoreDeltaRGBA32 () { int ptrDstLine = m_ptrDstBlock; diff --git a/ArcFormats/Eternity/ImageSGF.cs b/ArcFormats/Eternity/ImageSGF.cs index c14c40ec..3cf7952e 100644 --- a/ArcFormats/Eternity/ImageSGF.cs +++ b/ArcFormats/Eternity/ImageSGF.cs @@ -35,6 +35,7 @@ namespace GameRes.Formats.Eternity public bool HasAlpha; public int BlockSize; public uint DataOffset; + public uint AlphaOffset; } [Export(typeof(ImageFormat))] @@ -64,6 +65,7 @@ namespace GameRes.Formats.Eternity HasAlpha = header.ToInt32 (8) != 0, BlockSize = header.ToUInt16 (0xC), DataOffset = header.ToUInt32 (0x14), + AlphaOffset = header.ToUInt32 (0x1C), }; } @@ -87,13 +89,14 @@ namespace GameRes.Formats.Eternity byte[] m_output; public byte[] Data { get { return m_output; } } - public PixelFormat Format { get { return PixelFormats.Bgr24; } } + public PixelFormat Format { get; private set; } public SgfReader (IBinaryStream input, SgfMetaData info) { m_input = input; m_info = info; m_output = new byte[3 * info.Width * info.Height]; + Format = PixelFormats.Bgr24; } public byte[] Unpack () @@ -128,9 +131,79 @@ namespace GameRes.Formats.Eternity g = m_output[start_pos+1]; r = m_output[start_pos+2]; } + if (m_info.HasAlpha) + { + var alpha = ReadAlpha(); + if (alpha != null) + { + var pixels = new byte[m_info.iWidth * m_info.iHeight * 4]; + dst = 0; + int p = 0; + int a = 0; + while (dst < pixels.Length) + { + pixels[dst++] = m_output[p++]; + pixels[dst++] = m_output[p++]; + pixels[dst++] = m_output[p++]; + pixels[dst++] = alpha[a++]; + } + m_output = pixels; + Format = PixelFormats.Bgra32; + } + } return m_output; } + byte[] ReadAlpha () + { + m_input.Position = m_info.AlphaOffset; + var signature = m_input.ReadUInt16(); + if (0x2041 == signature) // 'A ' + return ReadASection(); + else if (0x4D42 == signature) // 'BM' + return ReadBmpSection(); + else + return null; + } + + byte[] ReadASection () + { + var alpha = new byte[m_info.iWidth * m_info.iHeight]; + m_input.Position = m_info.AlphaOffset + 8; + int block_size = m_input.ReadUInt16(); + m_input.Position = m_info.AlphaOffset + 0x10; + uint offset = m_input.ReadUInt32(); + uint next_pos = m_info.AlphaOffset + offset; + int height = (int)m_info.Height; + int dst = alpha.Length - m_info.iWidth; + byte a = 0; + for (int y = 0; y < height; ++y) + { + int start_pos = dst; + if (0 == (y % block_size)) + { + m_input.Position = next_pos; + next_pos += m_input.ReadUInt32(); + a = (byte)m_input.ReadUInt32(); + mask1 = mask2 = mask3 = mask4 = mask5 = 1; + } + for (uint x = 0; x < m_info.Width; ++x) + { + a = GetNextByte (a); + alpha[dst++] = a; + } + a = alpha[start_pos]; + dst = start_pos - m_info.iWidth; + } + return alpha; + } + + byte[] ReadBmpSection () + { + // throw new NotImplementedException ("ReadBmpSection not implemented."); + return null; + } + uint mask1; uint mask2; uint mask3; diff --git a/ArcFormats/ExHibit/ImageGYU.cs b/ArcFormats/ExHibit/ImageGYU.cs index 184e5858..734d413d 100644 --- a/ArcFormats/ExHibit/ImageGYU.cs +++ b/ArcFormats/ExHibit/ImageGYU.cs @@ -62,6 +62,11 @@ namespace GameRes.Formats.ExHibit public override string Description { get { return "ExHIBIT engine image format"; } } public override uint Signature { get { return 0x1A555947; } } // 'GYU' + public GyuFormat () + { + Extensions = new[] { "gyu", "lvg" }; + } + GyuMap DefaultScheme = new GyuMap { NumericKeys = new Dictionary>(), StringKeys = new Dictionary>(), diff --git a/ArcFormats/ExeFile.cs b/ArcFormats/ExeFile.cs index 263a783e..2e44ef4c 100644 --- a/ArcFormats/ExeFile.cs +++ b/ArcFormats/ExeFile.cs @@ -37,6 +37,8 @@ namespace GameRes.Formats ArcView m_file; Dictionary m_section_table; Section m_overlay; + uint m_image_base = 0; + List m_section_list; public ExeFile (ArcView file) { @@ -79,6 +81,16 @@ namespace GameRes.Formats } } + public uint ImageBase + { + get + { + if (0 == m_image_base) + InitImageBase(); + return m_image_base; + } + } + /// /// Structure representing section of executable file in the form of its offset and size. /// @@ -88,6 +100,16 @@ namespace GameRes.Formats public uint Size; } + public class ImageSection // IMAGE_SECTION_HEADER + { + public string Name; + public uint VirtualSize; + public uint VirtualAddress; + public uint SizeOfRawData; + public uint PointerToRawData; + public uint Characteristics; + } + /// /// Returns true if executable file contains section . /// @@ -140,6 +162,16 @@ namespace GameRes.Formats return -1; } + public Section SectionByOffset (long offset) + { + foreach (var section in Sections.Values) + { + if (offset >= section.Offset && offset < section.Offset + section.Size) + return section; + } + return new Section { Offset = Whole.Size, Size = 0 }; + } + public long FindAsciiString (Section section, string seq, int step = 1) { return FindString (section, Encoding.ASCII.GetBytes (seq), step); @@ -152,26 +184,101 @@ namespace GameRes.Formats return FindString (section, bytes, step); } + /// + /// Convert virtual address into raw file offset. + /// + public long GetAddressOffset (uint address) + { + var section = GetAddressSection (address); + if (null == section) + return m_file.MaxOffset; + uint rva = address - ImageBase; + return section.PointerToRawData + (rva - section.VirtualAddress); + } + + public string GetCString (uint address) + { + return GetCString (address, Encodings.cp932); + } + + static readonly byte[] ZeroByte = new byte[1] { 0 }; + + /// + /// Returns null-terminated string from specified virtual address. + /// + public string GetCString (uint address, Encoding enc) + { + var section = GetAddressSection (address); + if (null == section) + return null; + uint rva = address - ImageBase; + uint offset = section.PointerToRawData + (rva - section.VirtualAddress); + uint size = section.PointerToRawData + section.SizeOfRawData - offset; + long eos = FindString (new Section { Offset = offset, Size = size }, ZeroByte); + if (eos < 0) + return null; + return View.ReadString (offset, (uint)(eos - offset), enc); + } + + private ImageSection GetAddressSection (uint address) + { + var img_base = ImageBase; + if (address < img_base) + throw new ArgumentException ("Invalid virtual address."); + if (null == m_section_list) + InitSectionTable(); + uint rva = address - img_base; + foreach (var section in m_section_list) + { + if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData) + return section; + } + return null; + } + + private void InitImageBase () + { + long hdr_offset = GetHeaderOffset() + 0x18; + if (View.ReadUInt16 (hdr_offset) != 0x010B) + throw new InvalidFormatException ("File is not a valid Windows 32-bit executable."); + m_image_base = View.ReadUInt32 (hdr_offset+0x1C); // ImageBase + } + + private long GetHeaderOffset () + { + long pe_offset = View.ReadUInt32 (0x3C); + if (pe_offset >= m_file.MaxOffset-0x58 || !View.AsciiEqual (pe_offset, "PE\0\0")) + throw new InvalidFormatException ("File is not a valid Windows 32-bit executable."); + return pe_offset; + } + private void InitSectionTable () { - long pe_offset = m_file.View.ReadUInt32 (0x3C); - if (pe_offset >= m_file.MaxOffset-0x58 || !m_file.View.AsciiEqual (pe_offset, "PE\0\0")) - throw new InvalidFormatException ("File is not a valid win32 executable."); - - int opt_header = m_file.View.ReadUInt16 (pe_offset+0x14); // SizeOfOptionalHeader - long offset = m_file.View.ReadUInt32 (pe_offset+0x54); // SizeOfHeaders + long pe_offset = GetHeaderOffset(); + int opt_header = View.ReadUInt16 (pe_offset+0x14); // SizeOfOptionalHeader long section_table = pe_offset+opt_header+0x18; - int count = m_file.View.ReadUInt16 (pe_offset+6); // NumberOfSections + long offset = View.ReadUInt32 (pe_offset+0x54); // SizeOfHeaders + int count = View.ReadUInt16 (pe_offset+6); // NumberOfSections var table = new Dictionary (count); + var list = new List (count); if (section_table + 0x28*count < m_file.MaxOffset) { for (int i = 0; i < count; ++i) { - var name = m_file.View.ReadString (section_table, 8); - var section = new Section { - Size = m_file.View.ReadUInt32 (section_table+0x10), - Offset = m_file.View.ReadUInt32 (section_table+0x14) + var name = View.ReadString (section_table, 8); + var img_section = new ImageSection { + Name = name, + VirtualSize = View.ReadUInt32 (section_table+0x08), + VirtualAddress = View.ReadUInt32 (section_table+0x0C), + SizeOfRawData = View.ReadUInt32 (section_table+0x10), + PointerToRawData = View.ReadUInt32 (section_table+0x14), + Characteristics = View.ReadUInt32 (section_table+0x24), }; + var section = new Section { + Offset = img_section.PointerToRawData, + Size = img_section.SizeOfRawData + }; + list.Add (img_section); if (!table.ContainsKey (name)) table.Add (name, section); if (0 != section.Size) @@ -183,6 +290,7 @@ namespace GameRes.Formats m_overlay.Offset = offset; m_overlay.Size = (uint)(m_file.MaxOffset - offset); m_section_table = table; + m_section_list = list; } /// diff --git a/ArcFormats/FC01/ImageMCG.cs b/ArcFormats/FC01/ImageMCG.cs index 52a602a0..8490978b 100644 --- a/ArcFormats/FC01/ImageMCG.cs +++ b/ArcFormats/FC01/ImageMCG.cs @@ -112,6 +112,7 @@ namespace GameRes.Formats.FC01 { var options = Query (arcStrings.ArcImageEncrypted); key = options.Key; + LastKey = key; } else key = LastKey.Value; diff --git a/ArcFormats/FrontWing/ArcFLT.cs b/ArcFormats/FrontWing/ArcFLT.cs index ffb52d57..c5d3dc19 100644 --- a/ArcFormats/FrontWing/ArcFLT.cs +++ b/ArcFormats/FrontWing/ArcFLT.cs @@ -54,6 +54,11 @@ namespace GameRes.Formats.FrontWing public override bool IsHierarchic { get { return true; } } public override bool CanWrite { get { return false; } } + public FltOpener() + { + ContainedFormats = new[] { "FG/FWGI", "OGG", "DAT/GENERIC" }; + } + public override ArcFile TryOpen (ArcView file) { if (!file.View.AsciiEqual (4, "PACKDATA0000")) @@ -130,4 +135,9 @@ namespace GameRes.Formats.FrontWing 0x22, 0x45, 0xF2, 0x65, 0x74, 0x34, 0x35, 0xDE, 0x59, 0x27, 0xA3, 0xFB, 0x0C, 0x80, 0x32, 0xFF, }; } + + [Export(typeof(ResourceAlias))] + [ExportMetadata("Extension", "CSF")] + [ExportMetadata("Target", "DAT/GENERIC")] + public class CsfFormat : ResourceAlias { } } diff --git a/ArcFormats/FrontWing/ImageFG.cs b/ArcFormats/FrontWing/ImageFG.cs index 4f68a78d..b88d493d 100644 --- a/ArcFormats/FrontWing/ImageFG.cs +++ b/ArcFormats/FrontWing/ImageFG.cs @@ -23,9 +23,9 @@ // IN THE SOFTWARE. // +using System; using System.ComponentModel.Composition; using System.IO; -using System.Windows.Media.Imaging; using GameRes.Compression; namespace GameRes.Formats.FrontWing @@ -94,7 +94,7 @@ namespace GameRes.Formats.FrontWing { var fge_name = Path.ChangeExtension (file.Name, ".fge"); if (!VFS.FileExists (fge_name)) - return null; + throw new OperationCanceledException("Required metadata file '"+Path.GetFileName(fge_name)+"' not found."); using (var fg = OpenFg (file)) { return Fwgi.Value.ReadMetaData (fg); diff --git a/ArcFormats/GsPack/ArcGsPack.cs b/ArcFormats/GsPack/ArcGsPack.cs index 07efb74e..8f108a72 100644 --- a/ArcFormats/GsPack/ArcGsPack.cs +++ b/ArcFormats/GsPack/ArcGsPack.cs @@ -230,7 +230,7 @@ namespace GameRes.Formats.Gs } [Export(typeof(ScriptFormat))] - public class GsScriptFormat : ScriptFormat + public class GsScriptFormat : GenericScriptFormat { public override string Tag { get { return "SCW"; } } public override string Description { get { return "GsWin script file"; } } @@ -240,15 +240,5 @@ namespace GameRes.Formats.Gs { Signatures = new uint[] { 0x20574353, 0x35776353, 0x34776353 }; } - - public override ScriptData Read (string name, Stream file) - { - throw new NotImplementedException(); - } - - public override void Write (Stream file, ScriptData script) - { - throw new NotImplementedException(); - } } } diff --git a/ArcFormats/HSP/ArcDPM.cs b/ArcFormats/HSP/ArcDPM.cs index e0ebfae3..cb68e7db 100644 --- a/ArcFormats/HSP/ArcDPM.cs +++ b/ArcFormats/HSP/ArcDPM.cs @@ -42,7 +42,7 @@ namespace GameRes.Formats.HSP public DpmOpener () { - Extensions = new string[] { "dpm", "bin" }; + Extensions = new string[] { "dpm", "bin", "dat" }; Signatures = new uint[] { 0x584D5044, 0 }; } diff --git a/ArcFormats/Illusion/ArcPP.cs b/ArcFormats/Illusion/ArcPP.cs new file mode 100644 index 00000000..468d6aad --- /dev/null +++ b/ArcFormats/Illusion/ArcPP.cs @@ -0,0 +1,239 @@ +//! \file ArcPP.cs +//! \date 2022 Jun 01 +//! \brief Illusion resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel.Composition; + +namespace GameRes.Formats.Illusion +{ + [Serializable] + public class PpEncryptionScheme + { + public byte Method; + public uint[] Key; + } + + [Serializable] + public class PpScheme : ResourceScheme + { + public IDictionary KnownKeys; + } + + public class PpArchive : ArcFile + { + public readonly byte Method; + public readonly PpEncryptionScheme Scheme; + + public PpArchive (ArcView arc, ArchiveFormat impl, ICollection dir, byte encMethod, PpEncryptionScheme scheme) + : base (arc, impl, dir) + { + Method = encMethod; + Scheme = scheme; + } + } + + [Export(typeof(ArchiveFormat))] + public class PpOpener : ArchiveFormat + { + public override string Tag { get { return "PP/ILLUSION"; } } + public override string Description { get { return "Illusion resource archive"; } } + public override uint Signature { get { return 0x5650505B; } } // '[PPVER]' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + static readonly byte[][] DefaultIndexKey = new byte[][] { + new byte[] { 0xFA, 0x49, 0x7B, 0x1C, 0xF9, 0x4D, 0x83, 0x0A }, + new byte[] { 0x3A, 0xE3, 0x87, 0xC2, 0xBD, 0x1E, 0xA6, 0xFE } + }; + + public override ArcFile TryOpen (ArcView file) + { + if (!file.View.AsciiEqual (0, "[PPVER]\0")) + return null; + + var buffer = file.View.ReadBytes (8, 9); + + DecryptIndex (buffer, 0, 4); + int version = buffer.ToInt32 (0); + + DecryptIndex (buffer, 4, 1); + byte encryption_method = buffer[4]; + if (encryption_method > 4) + return null; + + DecryptIndex (buffer, 5, 4); + int count = buffer.ToInt32 (5); + if (!IsSaneCount (count)) + return null; + + if (version < 0x6C) + return null; + var dir = new List (count); + uint index_offset = 0x11; + uint index_size = (uint)(count * 0x120); + var index = file.View.ReadBytes (index_offset, index_size); + index_offset += index_size; + DecryptIndex (index, 0, index.Length); + int pos = 0; + for (int i = 0; i < count; ++i) + { + var name = Binary.GetCString (index, pos, 0x104); + pos += 0x104; + var entry = Create (name); + entry.Size = index.ToUInt32 (pos); + entry.Offset = index.ToUInt32 (pos+4); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + pos += 0x1C; + } + var scheme = QueryEncryptionScheme (file); + if (null == scheme) + return null; + return new PpArchive (file, this, dir, encryption_method, scheme); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var parc = arc as PpArchive; + if (null == parc || 2 == parc.Method) + return base.OpenEntry (arc, entry); + var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); + if (1 == parc.Method) + DecryptData1 (data, parc.Scheme); + else if (3 == parc.Method) + DecryptData3 (data, parc.Scheme); + else if (4 == parc.Method) + data = UnpackData (data); + return new BinMemoryStream (data, entry.Name); + } + + byte[] UnpackData (byte[] input) + { + return input; // decompression not implemented + } + + void DecryptData1 (byte[] data, PpEncryptionScheme scheme) + { + if (scheme.Method > 2 || scheme.Key.Length == 0) + return; + if (0 == scheme.Method) + { + for (int i = 0; i < data.Length; ++i) + { + data[i] ^= (byte)scheme.Key[i % scheme.Key.Length]; + } + return; + } + unsafe + { + fixed (byte* data8 = data) + { + if (1 == scheme.Method) + { + ushort* data16 = (ushort*)data8; + int size = data.Length / 2; + for (int i = 0; i < size; ++i) + { + data16[i] ^= (ushort)scheme.Key[i % scheme.Key.Length]; + } + } + else if (2 == scheme.Method) + { + uint* data32 = (uint*)data8; + int size = data.Length / 4; + for (int i = 0; i < size; ++i) + { + data32[i] ^= scheme.Key[i % scheme.Key.Length]; + } + } + } + } + } + + void DecryptData3 (byte[] data, PpEncryptionScheme scheme) + { + if (scheme.Key.Length < 8) + return; + var key0 = new ushort[] { (ushort)scheme.Key[0], (ushort)scheme.Key[1], (ushort)scheme.Key[2], (ushort)scheme.Key[3] }; + var key1 = new ushort[] { (ushort)scheme.Key[4], (ushort)scheme.Key[5], (ushort)scheme.Key[6], (ushort)scheme.Key[7] }; + unsafe + { + fixed (byte* data8 = data) + { + ushort* data16 = (ushort*)data8; + int size = data.Length / 2; + for (int i = 0; i < size; ++i) + { + int k = i & 3; + key0[k] += key1[k]; + data16[i] ^= key0[k]; + } + } + } + } + + internal void DecryptIndex (byte[] data, int pos, int length) + { + var key0 = DefaultIndexKey[0].Clone() as byte[]; + var key1 = DefaultIndexKey[1]; + for (int i = 0; i < length; ++i) + { + int k = i & 7; + key0[k] += key1[k]; + data[pos+i] ^= key0[k]; + } + } + + PpScheme DefaultScheme = new PpScheme + { + KnownKeys = new Dictionary() + }; + + internal IDictionary KnownKeys { get { return DefaultScheme.KnownKeys; } } + + public override ResourceScheme Scheme + { + get { return DefaultScheme; } + set { DefaultScheme = (PpScheme)value; } + } + + PpEncryptionScheme QueryEncryptionScheme (ArcView file) + { + var title = FormatCatalog.Instance.LookupGame (file.Name); + if (string.IsNullOrEmpty (title)) + title = FormatCatalog.Instance.LookupGame (file.Name, @"..\*.exe"); + if (string.IsNullOrEmpty (title)) + return null; + PpEncryptionScheme key; + if (!KnownKeys.TryGetValue (title, out key)) + return null; + return key; + } + } +} diff --git a/ArcFormats/Interheart/ArcFPK.cs b/ArcFormats/Interheart/ArcFPK.cs index e40b9806..f2083f1f 100644 --- a/ArcFormats/Interheart/ArcFPK.cs +++ b/ArcFormats/Interheart/ArcFPK.cs @@ -43,7 +43,7 @@ namespace GameRes.Formats.CandySoft public FpkOpener () { Signatures = new uint[] { 0, 1 }; - ContainedFormats = new[] { "BMP", "KG", "OGG", "SCR", "TXT" }; + ContainedFormats = new[] { "BMP", "KG", "OGG", "SCR", "TXT", "DAT/GENERIC" }; } public override ArcFile TryOpen (ArcView file) @@ -134,19 +134,19 @@ namespace GameRes.Formats.CandySoft public override Stream OpenEntry (ArcFile arc, Entry entry) { - var input = arc.File.CreateStream (entry.Offset, entry.Size); - if (entry.Size <= 8) - return input; - var sign = input.Signature; - if (0x32434c5a != sign) // 'ZLC2' - return input; - - using (input) - using (var reader = new Zlc2Reader (input, (int)entry.Size)) + IBinaryStream input = arc.File.CreateStream (entry.Offset, entry.Size); + while (input.Length > 8 && input.Signature == 0x32434C5A) // 'ZLC2' { - reader.Unpack(); - return new BinMemoryStream (reader.Data, entry.Name); + IBinaryStream unpacked; + using (input) + using (var reader = new Zlc2Reader (input, (int)input.Length)) + { + reader.Unpack(); + unpacked = new BinMemoryStream (reader.Data, entry.Name); + } + input = unpacked; } + return input.AsStream; } } diff --git a/ArcFormats/Interheart/ImageBMP.cs b/ArcFormats/Interheart/ImageBMP.cs new file mode 100644 index 00000000..16cb9e02 --- /dev/null +++ b/ArcFormats/Interheart/ImageBMP.cs @@ -0,0 +1,111 @@ +//! \file ImageBMP.cs +//! \date 2022 Jun 06 +//! \brief Candy Soft RLE-compressed bitmap. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media.Imaging; + +// [980925][Candy Soft] Osananajimi + +namespace GameRes.Formats.Interheart +{ + internal class BmpRleMetaData : ImageMetaData + { + public int HeaderSize; + public int UnpackedSize; + } + + [Export(typeof(ImageFormat))] + public class BmpRleFormat : ImageFormat + { + public override string Tag { get { return "BMP/RLE"; } } + public override string Description { get { return "Candy Soft RLE-compressed bitmap"; } } + public override uint Signature { get { return 0x32504D42; } } // 'BMP24' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x26); + if (!header.AsciiEqual ("BMP24RLE")) // also "BMP08RLE" and "BMP16RLE" + return null; + return new BmpRleMetaData { + Width = header.ToUInt32 (0x1A), + Height = header.ToUInt32 (0x1E), + BPP = header.ToUInt16 (0x24), + HeaderSize = header.ToInt32 (0x12), + UnpackedSize = header.ToInt32 (0x0A), + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (BmpRleMetaData)info; + var output = new byte[meta.UnpackedSize]; + file.Position = 8; + file.Read (output, 0, meta.HeaderSize); + var buffer = new byte[3]; + int dst = meta.HeaderSize; + // XXX BMMP08 and BMP16 bitmaps use exactly the same algorithm, just different pixel size + file.Read (buffer, 0, 3); + while (dst + 3 <= output.Length) + { + byte r = buffer[0]; + byte g = buffer[1]; + byte b = buffer[2]; + output[dst++] = b; + output[dst++] = g; + output[dst++] = r; + file.Read (buffer, 0, 3); + if (r == buffer[0] && g == buffer[1] && b == buffer[2]) + { + if (dst + 3 > output.Length) + break; + output[dst++] = b; + output[dst++] = g; + output[dst++] = r; + int count = file.ReadUInt16(); + while (count --> 0) + { + output[dst++] = b; + output[dst++] = g; + output[dst++] = r; + } + file.Read (buffer, 0, 3); + } + } + using (var input = new BinMemoryStream (output)) + { + var decoder = new BmpBitmapDecoder (input, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + var frame = decoder.Frames[0]; + frame.Freeze(); + return new ImageData (frame, info); + } + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("BmpRleFormat.Write not implemented"); + } + } +} diff --git a/ArcFormats/Interheart/ImageHMP.cs b/ArcFormats/Interheart/ImageHMP.cs new file mode 100644 index 00000000..12ec8f1f --- /dev/null +++ b/ArcFormats/Interheart/ImageHMP.cs @@ -0,0 +1,96 @@ +//! \file ImageHMP.cs +//! \date 2022 Jun 16 +//! \brief Candy Soft hover map. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Interheart +{ + [Export(typeof(ImageFormat))] + public class HmpFormat : ImageFormat + { + public override string Tag { get { return "HMP"; } } + public override string Description { get { return "Interheart hover map"; } } + public override uint Signature { get { return 0; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + if (!file.Name.HasExtension (".hmp")) + return null; + uint width = file.ReadUInt32(); + uint height = file.ReadUInt32(); + if (width == 0 || width > 0x7FFF || height == 0 || height > 0x7FFF) + return null; + return new ImageMetaData { Width = width, Height = height, BPP = 8 }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + file.Position = 8; + var pixels = file.ReadBytes (info.iWidth * info.iHeight); + return ImageData.Create (info, PixelFormats.Indexed8, DefaultPalette, pixels); +// return ImageData.Create (info, PixelFormats.Gray8, null, pixels); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("HmpFormat.Write not implemented"); + } + + static readonly BitmapPalette DefaultPalette = new BitmapPalette (GenerateColors()); + + static Color[] GenerateColors () + { + var colors = new Color[256]; + for (int i = 8; i < 256; ++i) + { + colors[i] = Color.FromRgb ((byte)i, (byte)i, (byte)i); + } + colors[0] = Color.FromRgb (0x00, 0x00, 0x00); + colors[1] = Color.FromRgb (0x00, 0x00, 0x7F); + colors[2] = Color.FromRgb (0x00, 0x7F, 0x00); + colors[3] = Color.FromRgb (0x00, 0x7F, 0x7F); + colors[4] = Color.FromRgb (0x7F, 0x00, 0x00); + colors[5] = Color.FromRgb (0x7F, 0x00, 0x7F); + colors[6] = Color.FromRgb (0x7F, 0x7F, 0x00); + colors[7] = Color.FromRgb (0x7F, 0x7F, 0x7F); + colors[8] = Color.FromRgb (0x00, 0x00, 0xFF); + colors[9] = Color.FromRgb (0x00, 0xFF, 0x00); + colors[10] = Color.FromRgb (0x00, 0xFF, 0xFF); + colors[11] = Color.FromRgb (0xFF, 0x00, 0x00); + colors[12] = Color.FromRgb (0xFF, 0x00, 0xFF); + colors[13] = Color.FromRgb (0xFF, 0xFF, 0x00); + colors[14] = Color.FromRgb (0xFF, 0xFF, 0xFF); + colors[15] = Color.FromRgb (0xFF, 0x00, 0x7F); + colors[16] = Color.FromRgb (0xFF, 0x7F, 0x00); + colors[16] = Color.FromRgb (0xFF, 0x7F, 0x7F); + colors[17] = Color.FromRgb (0x7F, 0x00, 0xFF); + colors[18] = Color.FromRgb (0xFF, 0xFF, 0x7F); + return colors; + } + } +} diff --git a/ArcFormats/Kaguya/ArcKaguya.cs b/ArcFormats/Kaguya/ArcKaguya.cs index 1d3c6b00..ee2b2d73 100644 --- a/ArcFormats/Kaguya/ArcKaguya.cs +++ b/ArcFormats/Kaguya/ArcKaguya.cs @@ -39,7 +39,7 @@ namespace GameRes.Formats.Kaguya [Export(typeof(ArchiveFormat))] public class ArcOpener : ArchiveFormat { - public override string Tag { get { return "ARI"; } } + public override string Tag { get { return "ARC/ARI"; } } public override string Description { get { return "KaGuYa script engine resource archive"; } } public override uint Signature { get { return 0x314c4657; } } // 'WFL1' public override bool IsHierarchic { get { return true; } } @@ -48,11 +48,12 @@ namespace GameRes.Formats.Kaguya public ArcOpener () { Extensions = new string[] { "arc" }; + ContainedFormats = new[] { "AP", "APS3", "OGG", "DAT/GENERIC" }; } public override ArcFile TryOpen (ArcView file) { - var reader = new IndexReader(); + var reader = new IndexReader (this); var dir = reader.ReadIndex (file); if (null == dir || 0 == dir.Count) return null; @@ -77,9 +78,15 @@ namespace GameRes.Formats.Kaguya internal class IndexReader { + ArchiveFormat m_format; byte[] m_name_buf = new byte[0x20]; List m_dir = new List(); + public IndexReader (ArchiveFormat format) + { + m_format = format; + } + public List ReadIndex (ArcView file) { string ari_name = Path.ChangeExtension (file.Name, "ari"); @@ -163,7 +170,7 @@ namespace GameRes.Formats.Kaguya else if (1 == entry.Mode) entry.Type = "image"; else - entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name); + entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name, m_format.ContainedFormats); } string ReadName (ArcView file, long offset, int name_len) @@ -246,4 +253,9 @@ namespace GameRes.Formats.Kaguya } #endregion } + + [Export(typeof(ResourceAlias))] + [ExportMetadata("Extension", "TBL")] + [ExportMetadata("Target", "DAT/GENERIC")] + public class TblFormat : ResourceAlias { } } diff --git a/ArcFormats/Kaguya/ArcLINK.cs b/ArcFormats/Kaguya/ArcLINK.cs index 6eacb2d8..ee61b8e6 100644 --- a/ArcFormats/Kaguya/ArcLINK.cs +++ b/ArcFormats/Kaguya/ArcLINK.cs @@ -228,8 +228,7 @@ namespace GameRes.Formats.Kaguya public virtual LinkEncryption GetEncryption () { - var params_dir = VFS.GetDirectoryName (m_input.Name); - var params_dat = VFS.CombinePath (params_dir, "params.dat"); + var params_dat = VFS.ChangeFileName (m_input.Name, "params.dat"); if (!VFS.FileExists (params_dat)) return null; @@ -555,8 +554,10 @@ namespace GameRes.Formats.Kaguya m_input.Position = start; SkipChunk(); m_title = ReadString(); - if (m_version.Major < 3) + if (m_version.Major < 2) m_input.ReadCString(); +// else +// SkipString(); SkipString(); SkipString(); m_input.ReadByte(); @@ -583,7 +584,7 @@ namespace GameRes.Formats.Kaguya { ReadHeader (0x17); - if ("幼なじみと甘~くエッチに過ごす方法" == m_title) + if ("幼なじみと甘~くエッチに過ごす方法" == m_title || "艶女医" == m_title) { int count = m_input.ReadUInt8(); for (int i = 0; i < count; ++i) @@ -595,8 +596,15 @@ namespace GameRes.Formats.Kaguya } SkipArray(); SkipArray(); - m_input.ReadInt32(); - return m_input.ReadBytes (240000); + if ("幼なじみと甘~くエッチに過ごす方法" == m_title) + { + m_input.ReadInt32(); + return m_input.ReadBytes (240000); + } + else + { + return ReadKey(); + } } else // 毎日がM! { diff --git a/ArcFormats/KiriKiri/CroixCrypt.cs b/ArcFormats/KiriKiri/CroixCrypt.cs new file mode 100644 index 00000000..a5b62b8e --- /dev/null +++ b/ArcFormats/KiriKiri/CroixCrypt.cs @@ -0,0 +1,166 @@ +//! \file CroixCrypt.cs +//! \date 2017 Dec 27 +//! \brief Croix encryption algorithm for KiriKiri. +// +// Copyright (C) 2017 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +namespace GameRes.Formats.KiriKiri +{ + [Serializable] + public class CroixCrypt : ICrypt + { +// ulong sigdata_checksum = 0xA86704CF2727BE76; + ulong sigdata_checksum = 0x6C04B9AB66EF2EF0; + + public override void Decrypt (Xp3Entry entry, long offset, byte[] data, int pos, int count) + { + uint v16 = 0x6EDC44A8; + uint v17 = 0x139E; + uint v19 = 0x4B93; + for (int i = 0; i < 0x3D; ++i) + { + v17 += byte_10014F64[i]; + v19 += v17; + } + v17 %= 0xFFEFu; + v19 %= 0xFFEFu; + uint v21 = v17 ^ (v19 << 16); + uint v22 = (v21 & 0xF | ((v21 & 0xFFFFFFF0) << 14)) << 3 + | ((v21 & 0x18000 | ((v21 & 0x1F00000 + | ((v21 & 0xE0000 | (v21 >> 1) & 0x7F000000) >> 13)) >> 3)) >> 1); + uint v25 = ~(((v16 & 0x78 | (v16 >> 14) & 0x3FF80) >> 3) | (v16 & 0xC000 | (v16 & 0x1F0000 + | ((v16 & 7 | 2 * (v16 & 0xFFFFFF80)) << 13)) << 3) << 1); + for (int i = 0; i < 0x3D; ++i) + { + v25 = dword_10014070[(v25 ^ byte_10014F64[i]) & 0xFF] ^ (v25 >> 8); + } + v25 = ~v25; + v25 = (v25 & 0xF | ((v25 & 0xFFFFFFF0) << 14)) << 3 + | (v25 & 0x18000 | ((v25 & 0x1F00000 | ((v25 & 0xE0000 | (v25 >> 1) & 0x7F000000) >> 13)) >> 3)) >> 1; + uint v29 = 0x5793CE00; + uint v71 = v22 ^ (v29 << 21); + uint v75 = v25 ^ (v29 >> 11); + ulong v33 = sigdata_checksum ^ 0x5793CE00u ^ v71 ^ ((ulong)v75 << 32); + uint v55 = (uint)(v33 >> 17); + uint hash = entry.Hash ^ v55 ^ 0x15C3F972u; + for (int i = 0; i < count; ++i) + { + int shift = (((int)offset + i) & 3) << 3; + uint v40 = data[pos+i] ^ (hash >> shift); + v40 -= 0xE3AD9ACBu >> shift; + v40 ^= (byte)(offset >> ((((int)offset + i) & 7) << 3)); + v40 += 0xFECAB9F2u >> shift; + data[pos+i] = (byte)v40; + } + hash = entry.Hash ^ 0x27D3BCA1; + for (int i = 0; i < count; ++i) + { + int shift = (((int)offset + i) & 3) << 3; + uint v40 = data[pos+i] ^ (hash >> shift); + v40 -= 0xE3779ACBu >> shift; + v40 ^= (byte)(offset >> ((((int)offset + i) & 7) << 3)); + v40 += 0xFDCAB972u >> shift; + data[pos+i] = (byte)v40; + } + hash = entry.Hash & 0x7FFFFFFF; + var v83 = new byte[0x1F]; + for (int i = 0; i < 0x1F; ++i) + { + v83[i] = (byte)hash; + hash = v55 ^ (hash >> 8 | (hash & 0xFF) << 23); + } + uint v58 = 0; + uint v59 = 0; + var v84 = new byte[0x3D]; + for (int i = 0; i < 0x3D; ++i) + { + byte v61 = (byte)v58; + v84[i] = v61; + v58 = v55 ^ (uint)(v59 << 24 | v58 >> 8); + v59 = v59 >> 8 | (uint)v61 << 21; + } + for (int i = 0; i < count; ++i) + { + long v63 = offset + i; + data[pos+i] ^= v83[v63 % 0x1F]; + data[pos+i] += (byte)(v55 ^ v84[v63 % 0x3D] ^ byte_10014F64[v63 % 0x3D]); + } + } + + static ulong v160 = 0xA5665A5F061EC576; + static ulong CRC = 0xE51804DAE70D133E; + +// static ulong v160 = 0xA6129778061EC576; +// static ulong CRC = 0xE4EFF66CE70D133E; + static byte[] byte_10014F64 = InitTable(); + + static byte[] InitTable () + { + var key = new byte[0x3D]; + uint v58 = (uint)(v160 + CRC); + uint v59 = (uint)((v160 + CRC) >> 32) & 0x1FFFFFFF; + for (int i = 0; i < 0x3D; ++i) + { + byte v61 = (byte)v58; + key[i] = v61; + v58 = v59 << 24 | v58 >> 8; + v59 = v59 >> 8 | (uint)v61 << 21; + } + return key; + } + + static readonly uint[] dword_10014070 = { + 0x00000000, 0x09073096, 0x120E612C, 0x1B0951BA, 0xFF6DC419, 0xF66AF48F, 0xED63A535, 0xE46495A3, + 0xFEDB8832, 0xF7DCB8A4, 0xECD5E91E, 0xE5D2D988, 0x01B64C2B, 0x08B17CBD, 0x13B82D07, 0x1ABF1D91, + 0xFDB71064, 0xF4B020F2, 0xEFB97148, 0xE6BE41DE, 0x02DAD47D, 0x0BDDE4EB, 0x10D4B551, 0x19D385C7, + 0x036C9856, 0x0A6BA8C0, 0x1162F97A, 0x1865C9EC, 0xFC015C4F, 0xF5066CD9, 0xEE0F3D63, 0xE7080DF5, + 0xFB6E20C8, 0xF269105E, 0xE96041E4, 0xE0677172, 0x0403E4D1, 0x0D04D447, 0x160D85FD, 0x1F0AB56B, + 0x05B5A8FA, 0x0CB2986C, 0x17BBC9D6, 0x1EBCF940, 0xFAD86CE3, 0xF3DF5C75, 0xE8D60DCF, 0xE1D13D59, + 0x06D930AC, 0x0FDE003A, 0x14D75180, 0x1DD06116, 0xF9B4F4B5, 0xF0B3C423, 0xEBBA9599, 0xE2BDA50F, + 0xF802B89E, 0xF1058808, 0xEA0CD9B2, 0xE30BE924, 0x076F7C87, 0x0E684C11, 0x15611DAB, 0x1C662D3D, + 0xF6DC4190, 0xFFDB7106, 0xE4D220BC, 0xEDD5102A, 0x09B18589, 0x00B6B51F, 0x1BBFE4A5, 0x12B8D433, + 0x0807C9A2, 0x0100F934, 0x1A09A88E, 0x130E9818, 0xF76A0DBB, 0xFE6D3D2D, 0xE5646C97, 0xEC635C01, + 0x0B6B51F4, 0x026C6162, 0x196530D8, 0x1062004E, 0xF40695ED, 0xFD01A57B, 0xE608F4C1, 0xEF0FC457, + 0xF5B0D9C6, 0xFCB7E950, 0xE7BEB8EA, 0xEEB9887C, 0x0ADD1DDF, 0x03DA2D49, 0x18D37CF3, 0x11D44C65, + 0x0DB26158, 0x04B551CE, 0x1FBC0074, 0x16BB30E2, 0xF2DFA541, 0xFBD895D7, 0xE0D1C46D, 0xE9D6F4FB, + 0xF369E96A, 0xFA6ED9FC, 0xE1678846, 0xE860B8D0, 0x0C042D73, 0x05031DE5, 0x1E0A4C5F, 0x170D7CC9, + 0xF005713C, 0xF90241AA, 0xE20B1010, 0xEB0C2086, 0x0F68B525, 0x066F85B3, 0x1D66D409, 0x1461E49F, + 0x0EDEF90E, 0x07D9C998, 0x1CD09822, 0x15D7A8B4, 0xF1B33D17, 0xF8B40D81, 0xE3BD5C3B, 0xEABA6CAD, + 0xEDB88320, 0xE4BFB3B6, 0xFFB6E20C, 0xF6B1D29A, 0x12D54739, 0x1BD277AF, 0x00DB2615, 0x09DC1683, + 0x13630B12, 0x1A643B84, 0x016D6A3E, 0x086A5AA8, 0xEC0ECF0B, 0xE509FF9D, 0xFE00AE27, 0xF7079EB1, + 0x100F9344, 0x1908A3D2, 0x0201F268, 0x0B06C2FE, 0xEF62575D, 0xE66567CB, 0xFD6C3671, 0xF46B06E7, + 0xEED41B76, 0xE7D32BE0, 0xFCDA7A5A, 0xF5DD4ACC, 0x11B9DF6F, 0x18BEEFF9, 0x03B7BE43, 0x0AB08ED5, + 0x16D6A3E8, 0x1FD1937E, 0x04D8C2C4, 0x0DDFF252, 0xE9BB67F1, 0xE0BC5767, 0xFBB506DD, 0xF2B2364B, + 0xE80D2BDA, 0xE10A1B4C, 0xFA034AF6, 0xF3047A60, 0x1760EFC3, 0x1E67DF55, 0x056E8EEF, 0x0C69BE79, + 0xEB61B38C, 0xE266831A, 0xF96FD2A0, 0xF068E236, 0x140C7795, 0x1D0B4703, 0x060216B9, 0x0F05262F, + 0x15BA3BBE, 0x1CBD0B28, 0x07B45A92, 0x0EB36A04, 0xEAD7FFA7, 0xE3D0CF31, 0xF8D99E8B, 0xF1DEAE1D, + 0x1B64C2B0, 0x1263F226, 0x096AA39C, 0x006D930A, 0xE40906A9, 0xED0E363F, 0xF6076785, 0xFF005713, + 0xE5BF4A82, 0xECB87A14, 0xF7B12BAE, 0xFEB61B38, 0x1AD28E9B, 0x13D5BE0D, 0x08DCEFB7, 0x01DBDF21, + 0xE6D3D2D4, 0xEFD4E242, 0xF4DDB3F8, 0xFDDA836E, 0x19BE16CD, 0x10B9265B, 0x0BB077E1, 0x02B74777, + 0x18085AE6, 0x110F6A70, 0x0A063BCA, 0x03010B5C, 0xE7659EFF, 0xEE62AE69, 0xF56BFFD3, 0xFC6CCF45, + 0xE00AE278, 0xE90DD2EE, 0xF2048354, 0xFB03B3C2, 0x1F672661, 0x166016F7, 0x0D69474D, 0x046E77DB, + 0x1ED16A4A, 0x17D65ADC, 0x0CDF0B66, 0x05D83BF0, 0xE1BCAE53, 0xE8BB9EC5, 0xF3B2CF7F, 0xFAB5FFE9, + 0x1DBDF21C, 0x14BAC28A, 0x0FB39330, 0x06B4A3A6, 0xE2D03605, 0xEBD70693, 0xF0DE5729, 0xF9D967BF, + 0xE3667A2E, 0xEA614AB8, 0xF1681B02, 0xF86F2B94, 0x1C0BBE37, 0x150C8EA1, 0x0E05DF1B, 0x0702EF8D, + }; + } +} diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs index 8e1149ad..e64c3e14 100644 --- a/ArcFormats/KiriKiri/CryptAlgorithms.cs +++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs @@ -1406,4 +1406,43 @@ namespace GameRes.Formats.KiriKiri return key; } } + + [Serializable] + public class GensouCrypt : ICrypt + { + byte[] Key1; + uint[] Key2; + + public GensouCrypt (byte[] key1, uint[] key2) + { + Key1 = key1; + Key2 = key2; + StartupTjsNotEncrypted = true; + } + + public override void Decrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count) + { + ushort off16 = (ushort)offset; + for (int i = 0; i < count; ++i) + { + buffer[pos+i] ^= (byte)(Key1[(Key2[off16 >> 3] >> ((off16 & 7) << 2)) & 0xF] + ^ ((Key2[off16 >> 3] ^ entry.Hash) >> ((off16 & 3) << 3))); + off16++; + } + } + + public override void Encrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count) + { + Decrypt (entry, offset, buffer, pos, count); + } + + public override void Init (ArcFile arc) + { + foreach (Xp3Entry entry in arc.Dir.Where (e => VFS.IsPathEqualsToFileName (e.Name, "btext.dll") + || VFS.IsPathEqualsToFileName (e.Name, "initialize.tjs"))) + { + entry.Cipher = Xp3Opener.NoCryptAlgorithm; + } + } + } } diff --git a/ArcFormats/Lambda/ImageCLS.cs b/ArcFormats/Lambda/ImageCLS.cs index a9876415..d4c88ab6 100644 --- a/ArcFormats/Lambda/ImageCLS.cs +++ b/ArcFormats/Lambda/ImageCLS.cs @@ -34,6 +34,7 @@ namespace GameRes.Formats.Lambda internal class ClsMetaData : ImageMetaData { public int FrameOffset; + public bool IsCompressed; } [Export(typeof(ImageFormat))] @@ -67,8 +68,7 @@ namespace GameRes.Formats.Lambda int y = file.ReadInt32(); file.Position = frame_offset+0x30; - if (file.ReadByte() != 1) - return null; + bool compressed = file.ReadByte() != 0; int format = file.ReadByte(); if (format != 4 && format != 5 && format != 2) return null; @@ -79,6 +79,7 @@ namespace GameRes.Formats.Lambda OffsetY = y, BPP = 8 * (format - 1), FrameOffset = frame_offset, + IsCompressed = compressed, }; } @@ -104,6 +105,7 @@ namespace GameRes.Formats.Lambda int m_channels; int m_base_offset; int[] m_rows_sizes; + bool m_compressed; public PixelFormat Format { get; private set; } public BitmapPalette Palette { get; private set; } @@ -112,6 +114,7 @@ namespace GameRes.Formats.Lambda { m_input = input; m_base_offset = info.FrameOffset; + m_compressed = info.IsCompressed; m_width = (int)info.Width; m_height = (int)info.Height; m_channels = info.BPP / 8; @@ -120,7 +123,7 @@ namespace GameRes.Formats.Lambda else if (4 == m_channels) Format = PixelFormats.Bgra32; else - Format = PixelFormats.Bgr32; + Format = PixelFormats.Bgr24; m_channel = new byte[m_width * m_height]; m_rows_sizes = new int[m_height]; } @@ -148,13 +151,20 @@ namespace GameRes.Formats.Lambda UnpackChannel (sizes[0]); return m_channel; } - var output = new byte[m_width * m_height * 4]; + else if (!m_compressed) + { + var pixels = new byte[sizes[0]]; + SetPosition (offsets[0]); + m_input.Read (pixels, 0, pixels.Length); + return pixels; + } + var output = new byte[m_width * m_height * m_channels]; for (int i = 0; i < m_channels; ++i) { SetPosition (offsets[i]); UnpackChannel (sizes[i]); int src = 0; - for (int dst = ChannelOrder[i]; dst < output.Length; dst += 4) + for (int dst = ChannelOrder[i]; dst < output.Length; dst += m_channels) { output[dst] = m_channel[src++]; } @@ -169,6 +179,11 @@ namespace GameRes.Formats.Lambda void UnpackChannel (int size) { + if (!m_compressed) + { + ReadV0 (size); + return; + } int method = Binary.BigEndian (m_input.ReadUInt16()); if (method > 1) throw new InvalidFormatException(); diff --git a/ArcFormats/Liar/ArcXFL.cs b/ArcFormats/Liar/ArcXFL.cs index dcfc7bca..c3f5ae53 100644 --- a/ArcFormats/Liar/ArcXFL.cs +++ b/ArcFormats/Liar/ArcXFL.cs @@ -181,7 +181,7 @@ namespace GameRes.Formats.Liar } //[Export(typeof(ScriptFormat))] - public class GscFormat : ScriptFormat + public class GscFormat : GenericScriptFormat { public override string Tag { get { return "GSC"; } } public override string Description { get { return Strings.arcStrings.GSCDescription; } } diff --git a/ArcFormats/Lilim/ArcAOS.cs b/ArcFormats/Lilim/ArcAOS.cs index 3f82c258..5c4e030d 100644 --- a/ArcFormats/Lilim/ArcAOS.cs +++ b/ArcFormats/Lilim/ArcAOS.cs @@ -41,6 +41,11 @@ namespace GameRes.Formats.Lilim public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } + public AosOpener () + { + ContainedFormats = new[] { "BMP", "ABM", "IMG/BMP", "DAT/GENERIC", "OGG" }; + } + static readonly byte[] IndexLink = Enumerable.Repeat (0xff, 0x10).ToArray(); static readonly byte[] IndexEnd = Enumerable.Repeat (0, 0x10).ToArray(); diff --git a/ArcFormats/Macromedia/ArcCCT.cs b/ArcFormats/Macromedia/ArcCCT.cs index 53f22cca..e722b2a8 100644 --- a/ArcFormats/Macromedia/ArcCCT.cs +++ b/ArcFormats/Macromedia/ArcCCT.cs @@ -32,13 +32,13 @@ using System.Text; using GameRes.Compression; using GameRes.Utility; -namespace GameRes.Formats.Selen +namespace GameRes.Formats.Macromedia { [Export(typeof(ArchiveFormat))] public class CctOpener : ArchiveFormat { public override string Tag { get { return "CCT"; } } - public override string Description { get { return "Macromedia Director resource archive"; } } + public override string Description { get { return "Macromedia Shockwave resource archive"; } } public override uint Signature { get { return 0x52494658; } } // 'XFIR' public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } diff --git a/ArcFormats/Macromedia/ArcDXR.cs b/ArcFormats/Macromedia/ArcDXR.cs new file mode 100644 index 00000000..ae043c3d --- /dev/null +++ b/ArcFormats/Macromedia/ArcDXR.cs @@ -0,0 +1,286 @@ +//! \file ArcDXR.cs +//! \date 2023 Aug 17 +//! \brief Macromedia Director presentation container. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Macromedia +{ + [Export(typeof(ArchiveFormat))] + public class DxrOpener : ArchiveFormat + { + public override string Tag { get => "DXR"; } + public override string Description { get => "Macromedia Director resource archive"; } + public override uint Signature { get => 0x52494658; } // 'XFIR' + public override bool IsHierarchic { get => false; } + public override bool CanWrite { get => false; } + + public DxrOpener () + { + Extensions = new[] { "dxr", "cxt" }; + Signatures = new[] { 0x52494658u, 0x58464952u }; + } + + internal static readonly HashSet RawChunks = new HashSet { + "RTE0", "RTE1", "FXmp", "VWFI", "VWSC", "Lscr", "STXT", + }; + + internal bool ConvertText = true; + + public override ArcFile TryOpen (ArcView file) + { + using (var input = file.CreateStream()) + { + ByteOrder ord = input.Signature == 0x52494658u ? ByteOrder.LittleEndian : ByteOrder.BigEndian; + var reader = new Reader (input, ord); + reader.Position = 4; + uint length = reader.ReadU32(); + var context = new SerializationContext(); + var dir_file = new DirectorFile(); + if (!dir_file.Deserialize (context, reader)) + return null; + + var dir = new List (); + ImportMedia (dir_file, dir); + foreach (MemoryMapEntry entry in dir_file.MMap.Dir) + { + if (RawChunks.Contains (entry.FourCC)) + { + entry.Name = string.Format ("{0:D6}.{1}", entry.Id, entry.FourCC.Trim()); + dir.Add (entry); + } + } + return new ArcFile (file, this, dir); + } + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var snd = entry as SoundEntry; + if (snd != null) + return OpenSound (arc, snd); + var ment = entry as MemoryMapEntry; + if (!ConvertText || null == ment || ment.FourCC != "STXT") + return base.OpenEntry (arc, entry); + uint offset = Binary.BigEndian (arc.File.View.ReadUInt32 (entry.Offset)); + uint length = Binary.BigEndian (arc.File.View.ReadUInt32 (entry.Offset + 4)); + return arc.File.CreateStream (entry.Offset + offset, length); + } + + internal Stream OpenSound (ArcFile arc, SoundEntry entry) + { + var header = arc.File.View.ReadBytes (entry.Header.Offset, entry.Header.Size); + var format = entry.DeserializeHeader (header); + var riff = new MemoryStream (0x2C); + WaveAudio.WriteRiffHeader (riff, format, entry.Size); + if (format.BitsPerSample < 16) + { + using (riff) + { + var input = arc.File.CreateStream (entry.Offset, entry.Size); + return new PrefixStream (riff.ToArray(), input); + } + } + // samples are stored in big-endian format + var samples = arc.File.View.ReadBytes (entry.Offset, entry.Size); + for (int i = 1; i < samples.Length; i += 2) + { + byte s = samples[i-1]; + samples[i-1] = samples[i]; + samples[i] = s; + } + riff.Write (samples, 0, samples.Length); + riff.Position = 0; + return riff; + } + + void ImportMedia (DirectorFile dir_file, List dir) + { + var seen_ids = new HashSet(); + var mmap = dir_file.MMap; + foreach (var cast in dir_file.Casts) + { + foreach (var piece in cast.Members.Values) + { + if (seen_ids.Contains (piece.Id)) + continue; + seen_ids.Add (piece.Id); + Entry entry = null; + if (piece.Type == DataType.Bitmap) + entry = ImportBitmap (piece, dir_file, cast); + else if (piece.Type == DataType.Sound) + entry = ImportSound (piece, dir_file); + if (entry != null) + dir.Add (entry); + } + } + } + + Entry ImportSound (CastMember sound, DirectorFile dir_file) + { + var sndHrec = dir_file.KeyTable.FindByCast (sound.Id, "sndH"); + var sndSrec = dir_file.KeyTable.FindByCast (sound.Id, "sndS"); + if (sndHrec == null || sndSrec == null) + return null; + var name = sound.Info.Name; + var sndH = dir_file.MMap[sndHrec.Id]; + var sndS = dir_file.MMap[sndSrec.Id]; + if (string.IsNullOrEmpty (name)) + name = sndSrec.Id.ToString ("D6"); + return new SoundEntry + { + Name = name + ".snd", + Type = "audio", + Offset = sndS.Offset, + Size = sndS.Size, + Header = sndH, + }; + } + + Entry ImportBitmap (CastMember bitmap, DirectorFile dir_file, Cast cast) + { + var bitd = dir_file.KeyTable.FindByCast (bitmap.Id, "BITD"); + if (bitd == null) + return null; + var entry = new BitmapEntry(); + entry.DeserializeHeader (bitmap.SpecificData); + var name = bitmap.Info.Name; + if (string.IsNullOrEmpty (name)) + name = bitd.Id.ToString ("D6"); + var chunk = dir_file.MMap[bitd.Id]; + entry.Name = name + ".BITD"; + entry.Type = "image"; + entry.Offset = chunk.Offset; + entry.Size = chunk.Size; + if (entry.Palette > 0) + { + var cast_id = cast.Index[entry.Palette-1]; + var clut = dir_file.KeyTable.FindByCast (cast_id, "CLUT"); + if (clut != null) + entry.PaletteRef = dir_file.MMap[clut.Id]; + } + return entry; + } + + public override IImageDecoder OpenImage (ArcFile arc, Entry entry) + { + var bent = entry as BitmapEntry; + if (null == bent) + return base.OpenImage (arc, entry); + BitmapPalette palette = null; + if (bent.PaletteRef != null) + { + var pal_bytes = arc.File.View.ReadBytes (bent.PaletteRef.Offset, bent.PaletteRef.Size); + palette = ReadPalette (pal_bytes); + } + else if (bent.BitDepth <= 8) + { + switch (bent.Palette) + { + case 0: palette = Palettes.SystemMac; break; + case -1: palette = Palettes.Rainbow; break; + case -2: palette = Palettes.Grayscale; break; + case -100: palette = Palettes.WindowsDirector4; break; + default: + case -101: palette = Palettes.SystemWindows; break; + } + } + var input = arc.File.CreateStream (entry.Offset, entry.Size); + var info = new ImageMetaData { + Width = (uint)(bent.Right - bent.Left), + Height = (uint)(bent.Bottom - bent.Top), + BPP = bent.BitDepth + }; + return new BitdDecoder (input.AsStream, info, palette); + } + + BitmapPalette ReadPalette (byte[] data) + { + int num_colors = data.Length / 6; + var colors = new Color[num_colors]; + for (int i = 0; i < data.Length; i += 6) + { + colors[i/6] = Color.FromRgb (data[i], data[i+2], data[i+4]); + } + return new BitmapPalette (colors); + } + } + + internal class BitmapEntry : Entry + { + public byte Flags; + public byte DepthType; + public int Top; + public int Left; + public int Bottom; + public int Right; + public int BitDepth; + public int Palette; + public Entry PaletteRef; + + public void DeserializeHeader (byte[] data) + { + using (var input = new MemoryStream (data, false)) + { + var reader = new Reader (input, ByteOrder.BigEndian); + DepthType = reader.ReadU8(); + Flags = reader.ReadU8(); + Top = reader.ReadI16(); + Left = reader.ReadI16(); + Bottom = reader.ReadI16(); + Right = reader.ReadI16(); + reader.Skip (0x0C); + BitDepth = reader.ReadU16() & 0xFF; // ??? + reader.Skip (2); + Palette = reader.ReadI16(); + } + } + } + + internal class SoundEntry : Entry + { + public Entry Header; + + public WaveFormat DeserializeHeader (byte[] header) + { + // pure guesswork + return new WaveFormat { + FormatTag = 1, + Channels = (ushort)BigEndian.ToUInt32 (header, 0x4C), + SamplesPerSecond = BigEndian.ToUInt32 (header, 0x2C), + AverageBytesPerSecond = BigEndian.ToUInt32 (header, 0x30), + BlockAlign = (ushort)BigEndian.ToUInt32 (header, 0x50), + BitsPerSample = (ushort)BigEndian.ToUInt32 (header, 0x44), + }; + } + } +} diff --git a/ArcFormats/Macromedia/DirectorFile.cs b/ArcFormats/Macromedia/DirectorFile.cs new file mode 100644 index 00000000..2f84b1d0 --- /dev/null +++ b/ArcFormats/Macromedia/DirectorFile.cs @@ -0,0 +1,712 @@ +//! \file DirectorFile.cs +//! \date 2023 Aug 21 +//! \brief Macromedia Director container deserialization. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GameRes.Formats.Macromedia +{ + internal enum ByteOrder + { + LittleEndian, BigEndian + } + + internal enum DataType + { + Null = 0, + Bitmap = 1, + FilmLoop = 2, + Text = 3, + Palette = 4, + Picture = 5, + Sound = 6, + Button = 7, + Shape = 8, + Movie = 9, + DigitalVideo = 10, + Script = 11, + RTE = 12, + } + + internal class SerializationContext + { + public int Version; + public Encoding Encoding; + + public SerializationContext () + { + Encoding = Encodings.cp932; + } + } + + internal class DirectorFile + { + MemoryMap m_mmap = new MemoryMap(); + KeyTable m_keyTable = new KeyTable(); + DirectorConfig m_config = new DirectorConfig(); + List m_casts = new List(); + + public MemoryMap MMap => m_mmap; + public KeyTable KeyTable => m_keyTable; + public DirectorConfig Config => m_config; + public List Casts => m_casts; + + public bool Deserialize (SerializationContext context, Reader reader) + { + reader.Position = 8; + string codec = reader.ReadFourCC(); + if (codec != "MV93" && codec != "MC95") + return false; + return ReadMMap (context, reader) + && ReadKeyTable (context, reader) + && ReadConfig (context, reader) + && ReadCasts (context, reader); + } + + bool ReadMMap (SerializationContext context, Reader reader) + { + if (reader.ReadFourCC() != "imap") + return false; + reader.Skip (8); + uint mmap_pos = reader.ReadU32(); + reader.Position = mmap_pos; + if (reader.ReadFourCC() != "mmap") + return false; + reader.Position = mmap_pos + 8; + MMap.Deserialize (context, reader); + return true; + } + + bool ReadKeyTable (SerializationContext context, Reader reader) + { + var key_chunk = MMap.Find ("KEY*"); + if (null == key_chunk) + return false; + reader.Position = key_chunk.Offset; + KeyTable.Deserialize (context, reader); + return true; + } + + bool ReadConfig (SerializationContext context, Reader reader) + { + var config_chunk = MMap.Find ("VWCF") ?? MMap.Find ("DRCF"); + if (null == config_chunk) + return false; + reader.Position = config_chunk.Offset; + Config.Deserialize (context, reader); + context.Version = Config.Version; + return true; + } + + bool ReadCasts (SerializationContext context, Reader reader) + { + if (context.Version > 1200) + { + var mcsl = MMap.Find ("MCsL"); + if (mcsl != null) + { + reader.Position = mcsl.Offset; + var cast_list = new CastList(); + cast_list.Deserialize (context, reader); + foreach (var entry in cast_list.Entries) + { + var key_entry = KeyTable.FindByCast (entry.Id, "CAS*"); + if (key_entry != null) + { + var mmap_entry = MMap[key_entry.Id]; + var cast = new Cast (context, reader, mmap_entry); + if (!PopulateCast (cast, context, reader, entry)) + return false; + Casts.Add (cast); + } + } + return true; + } + } + var cas_chunk = MMap.Find ("CAS*"); + if (null == cas_chunk) + return false; + var new_entry = new CastListEntry { Name = "internal", Id = 0x400, MinMember = Config.MinMember }; + var new_cast = new Cast (context, reader, cas_chunk); + if (!PopulateCast (new_cast, context, reader, new_entry)) + return false; + Casts.Add (new_cast); + return true; + } + + public bool PopulateCast (Cast cast, SerializationContext context, Reader reader, CastListEntry entry) + { + cast.Name = entry.Name; + /* + var lctx_ref = KeyTable.Table.Find (e => e.CastId == entry.Id && (e.FourCC == "Lctx" || e.FourCC == "LctX")); + MemoryMapEntry lctx_chunk = null; + if (lctx_ref != null) + lctx_chunk = MMap[lctx_ref.Id]; + else + lctx_chunk = MMap.Dir.Find (e => e.FourCC == "Lctx" || e.FourCC == "LctX"); + if (null == lctx_chunk) + return false; + reader.Position = lctx_chunk.Offset; + var lctx = new ScriptContext(); + lctx.Deserialize (context, reader); + cast.Context = lctx; + */ + for (int i = 0; i < cast.Index.Length; ++i) + { + int chunk_id = cast.Index[i]; + if (chunk_id > 0) + { + var chunk = MMap[chunk_id]; + var member = new CastMember(); + member.Id = chunk_id; + reader.Position = chunk.Offset; + member.Deserialize (context, reader); + cast.Members[member.Id] = member; + } + } + return true; + } + } + + internal class CastMember + { + public DataType Type; + public CastInfo Info = new CastInfo(); + public byte[] SpecificData; + public byte Flags; + public int Id; + + public void Deserialize (SerializationContext context, Reader reader) + { + reader = reader.CloneUnless (ByteOrder.BigEndian); + if (context.Version > 1200) + { + Type = (DataType)reader.ReadI32(); + int info_length = reader.ReadI32(); + int data_length = reader.ReadI32(); + if (info_length > 0) + { + Info.Deserialize (context, reader); + } + SpecificData = reader.ReadBytes (data_length); + } + else + { + int data_length = reader.ReadU16(); + int info_length = reader.ReadI32(); + Type = (DataType)reader.ReadU8(); + --data_length; + if (data_length > 0) + { + Flags = reader.ReadU8(); + --data_length; + } + SpecificData = reader.ReadBytes (data_length); + if (info_length > 0) + { + Info.Deserialize (context, reader); + } + } + } + } + + internal class CastInfo + { + public uint DataOffset; + public uint ScriptKey; + public uint Flags; + public int ScriptId; + public string Name; + public string SourceText; + public List Items = new List(); + + public void Deserialize (SerializationContext context, Reader reader) + { + long base_offset = reader.Position; + DataOffset = reader.ReadU32(); + ScriptKey = reader.ReadU32(); + reader.Skip (4); + Flags = reader.ReadU32(); + ScriptId = reader.ReadI32(); + reader.Position = base_offset + DataOffset; + int table_len = reader.ReadU16(); + var offsets = new int[table_len]; + for (int i = 0; i < table_len; ++i) + offsets[i] = reader.ReadI32(); + + int data_length = reader.ReadI32(); + long list_offset = reader.Position; + Items.Clear(); + Items.Capacity = offsets.Length; + for (int i = 0; i < offsets.Length; ++i) + { + int offset = offsets[i]; + int next_offset = (i + 1 < offsets.Length) ? offsets[i+1] : data_length; + reader.Position = list_offset + offset; + Items.Add (reader.ReadBytes (next_offset - offset)); + } + + SourceText = Items.Count > 0 ? Binary.GetCString (Items[0], 0) : string.Empty; + Name = GetString (1, context.Encoding); + } + + string GetString (int item_idx, Encoding enc) + { + if (item_idx >= Items.Count) + return string.Empty; + var src = Items[item_idx]; + if (src.Length <= 1 || 0 == src[0]) + return string.Empty; + int len = src[0]; + return enc.GetString (src, 1, len); + } + } + + internal class Cast + { + public int[] Index; + public string Name; + public Dictionary Members = new Dictionary(); + + public Cast (SerializationContext context, Reader reader, MemoryMapEntry entry) + { + int count = (int)(entry.Size / 4); + Index = new int[count]; + reader.Position = entry.Offset; + Deserialize (context, reader); + } + + public void Deserialize (SerializationContext context, Reader reader) + { + reader = reader.CloneUnless (ByteOrder.BigEndian); + for (int i = 0; i < Index.Length; ++i) + Index[i] = reader.ReadI32(); + } + } + + internal class CastList + { + public uint DataOffset; + public int OffsetCount; + public int[] OffsetTable; + public int ItemsLength; + public int CastCount; + public int ItemsPerCast; + public List Items = new List(); + + public readonly List Entries = new List(); + + public void Deserialize (SerializationContext context, Reader reader) + { + long base_offset = reader.Position; + reader = reader.CloneUnless (ByteOrder.BigEndian); + DataOffset = reader.ReadU32(); + reader.Skip (2); + CastCount = reader.ReadU16(); + ItemsPerCast = reader.ReadU16(); + reader.Skip (2); + reader.Position = base_offset + DataOffset; + OffsetCount = reader.ReadU16(); + OffsetTable = new int[OffsetCount]; + for (int i = 0; i < OffsetCount; ++i) + { + OffsetTable[i] = reader.ReadI32(); + } + ItemsLength = reader.ReadI32(); + long items_offset = reader.Position; + Items.Clear(); + Items.Capacity = OffsetCount; + for (int i = 0; i < OffsetCount; ++i) + { + int offset = OffsetTable[i]; + int next_offset = (i + 1 < OffsetCount) ? OffsetTable[i + 1] : ItemsLength; + int item_size = next_offset - offset; + Items.Add (reader.ReadBytes (item_size)); + } + + Entries.Clear(); + Entries.Capacity = CastCount; + int item_idx = 0; + for (int i = 0; i < CastCount; ++i) + { + var entry = new CastListEntry(); + if (ItemsPerCast >= 1) + entry.Name = GetString (item_idx + 1, context.Encoding); + if (ItemsPerCast >= 2) + entry.Path = GetString (item_idx + 2, context.Encoding); + if (ItemsPerCast >= 3 && Items[item_idx + 3].Length >= 2) + entry.Flags = BigEndian.ToUInt16 (Items[item_idx + 3], 0); + if (ItemsPerCast >= 4 && Items[item_idx + 4].Length >= 8) + { + entry.MinMember = BigEndian.ToUInt16 (Items[item_idx + 4], 0); + entry.MaxMember = BigEndian.ToUInt16 (Items[item_idx + 4], 2); + entry.Id = BigEndian.ToInt32 (Items[item_idx + 4], 4); + } + Entries.Add (entry); + } + } + + string GetString (int item_idx, Encoding enc) + { + var src = Items[item_idx]; + if (src.Length <= 1 || 0 == src[0]) + return string.Empty; + int len = src[0]; + return enc.GetString (src, 1, len); + } + } + + internal class CastListEntry + { + public string Name; + public string Path; + public ushort Flags; + public int MinMember; + public int MaxMember; + public int Id; + } + + internal class ScriptContext + { + public int EntriesOffset; + public int LnamChunkId; + public int ValidCount; + public ushort Flags; + public short FreePtr; + public List ChunkMap = new List(); + + public void Deserialize (SerializationContext context, Reader reader) + { + long base_offset = reader.Position; + reader = reader.CloneUnless (ByteOrder.BigEndian); + reader.Skip (8); + int count = reader.ReadI32(); + reader.Skip (4); + EntriesOffset = reader.ReadU16(); + reader.Skip (14); + LnamChunkId = reader.ReadI32(); + ValidCount = reader.ReadU16(); + Flags = reader.ReadU16(); + FreePtr = reader.ReadI16(); + reader.Position = base_offset + EntriesOffset; + + ChunkMap.Clear(); + ChunkMap.Capacity = count; + for (int i = 0; i < count; ++i) + { + var entry = new ScriptContextMap(); + entry.Deserialize (context, reader); + ChunkMap.Add (entry); + } + } + } + + internal class ScriptContextMap + { + public int Key; + public int ChunkId; + + public void Deserialize (SerializationContext context, Reader reader) + { + Key = reader.ReadI32(); + ChunkId = reader.ReadI32(); + reader.Skip (4); + } + } + + internal class DirectorConfig + { + public short Length; + public short FileVersion; + public short StageTop; + public short StageLeft; + public short StageBottom; + public short StageRight; + public short MinMember; + public short MaxMember; + public ushort StageColor; + public ushort BitDepth; + public int Version; + public int FrameRate; + public int Platform; + public int Protection; + public uint CheckSum; + public int DefaultPalette; + + public void Deserialize (SerializationContext context, Reader reader) + { + long base_offset = reader.Position; + reader = reader.CloneUnless (ByteOrder.BigEndian); + + reader.Position = base_offset + 0x24; + Version = reader.ReadU16(); + reader.Position = base_offset; + Length = reader.ReadI16(); + FileVersion = reader.ReadI16(); + StageTop = reader.ReadI16(); + StageLeft = reader.ReadI16(); + StageBottom = reader.ReadI16(); + StageRight = reader.ReadI16(); + MinMember = reader.ReadI16(); + MaxMember = reader.ReadI16(); + reader.Skip (0x0A); + StageColor = reader.ReadU16(); + BitDepth = reader.ReadU16(); + reader.Skip (0x18); + FrameRate = reader.ReadU16(); + Platform = reader.ReadI16(); + Protection = reader.ReadI16(); + reader.Skip (4); + CheckSum = reader.ReadU32(); + if (Version > 1200) + { + reader.Position = base_offset + 0x4E; + } + else + { + reader.Position = base_offset + 0x46; + } + DefaultPalette = reader.ReadU16(); + } + } + + internal class KeyTable + { + public int EntrySize; + public int TotalCount; + public int UsedCount; + public readonly List Table = new List(); + + public KeyTableEntry this[int index] => Table[index]; + + public KeyTableEntry FindByCast (int cast_id, string four_cc) + { + return Table.Find (e => e.CastId == cast_id && e.FourCC == four_cc); + } + + public void Deserialize (SerializationContext context, Reader reader) + { + EntrySize = reader.ReadU16(); + reader.Skip(2); + TotalCount = reader.ReadI32(); + UsedCount = reader.ReadI32(); + + Table.Clear(); + Table.Capacity = TotalCount; + for (int i = 0; i < TotalCount; ++i) + { + var entry = new KeyTableEntry(); + entry.Deserialize (context, reader); + Table.Add (entry); + } + } + } + + internal class KeyTableEntry + { + public int Id; + public int CastId; + public string FourCC; + + public void Deserialize (SerializationContext context, Reader input) + { + Id = input.ReadI32(); + CastId = input.ReadI32(); + FourCC = input.ReadFourCC(); + } + } + + internal class MemoryMap + { + public ushort HeaderLength; + public ushort EntryLength; + public int ChunkCountMax; + public int ChunkCountUsed; + public int FreeHead; + public readonly List Dir = new List(); + + public MemoryMapEntry this[int index] => Dir[index]; + + public MemoryMapEntry Find (string four_cc) => Dir.Find (e => e.FourCC == four_cc); + + public void Deserialize (SerializationContext context, Reader reader) + { + long header_pos = reader.Position; + HeaderLength = reader.ReadU16(); + if (HeaderLength < 0x18) + throw new InvalidFormatException ("Invalid header length."); + EntryLength = reader.ReadU16(); + if (EntryLength < 0x14) + throw new InvalidFormatException ("Invalid entry length."); + ChunkCountMax = reader.ReadI32(); + ChunkCountUsed = reader.ReadI32(); + reader.Skip (8); + FreeHead = reader.ReadI32(); + + Dir.Clear(); + Dir.Capacity = ChunkCountUsed; + long entry_pos = header_pos + HeaderLength; + for (int i = 0; i < ChunkCountUsed; ++i) + { + reader.Position = entry_pos; + var entry = new MemoryMapEntry (i); + entry.Deserialize (context, reader); + Dir.Add (entry); + entry_pos += EntryLength; + } + } + } + + internal class MemoryMapEntry : Entry + { + public int Id; + public string FourCC; + public ushort Flags; + + public MemoryMapEntry (int id = 0) + { + Id = id; + } + + public void Deserialize (SerializationContext context, Reader reader) + { + FourCC = reader.ReadFourCC(); + Size = reader.ReadU32(); + Offset = reader.ReadU32() + 8; + Flags = reader.ReadU16(); + int Next = reader.ReadI32(); + } + } + + internal class Reader + { + Stream m_input; + byte[] m_buffer = new byte[4]; + + public Reader (Stream input, ByteOrder e = ByteOrder.LittleEndian) : this (input, Encodings.cp932, e) + { + } + + public Reader (Stream input, Encoding enc, ByteOrder e = ByteOrder.LittleEndian) + { + m_input = input; + Encoding = enc; + SetByteOrder (e); + } + + public Stream Source { get => m_input; } + + public ByteOrder ByteOrder { get; private set; } + + public Encoding Encoding { get; set; } + + public long Position + { + get => m_input.Position; + set => m_input.Position = value; + } + + private Func ToU16; + private Func ToU32; + + public void SetByteOrder (ByteOrder e) + { + this.ByteOrder = e; + if (ByteOrder.LittleEndian == e) + { + ToU16 = () => LittleEndian.ToUInt16 (m_buffer, 0); + ToU32 = () => LittleEndian.ToUInt32 (m_buffer, 0); + } + else + { + ToU16 = () => BigEndian.ToUInt16 (m_buffer, 0); + ToU32 = () => BigEndian.ToUInt32 (m_buffer, 0); + } + } + + static Dictionary KnownFourCC = new Dictionary(); + + public string ReadFourCC () + { + uint signature = ReadU32(); + string four_cc; + if (KnownFourCC.TryGetValue (signature, out four_cc)) + return four_cc; + BigEndian.Pack (signature, m_buffer, 0); + return KnownFourCC[signature] = Encoding.GetString (m_buffer, 0, 4); + } + + public void Skip (int amount) => m_input.Seek (amount, SeekOrigin.Current); + + public byte ReadU8 () + { + int b = m_input.ReadByte(); + if (-1 == b) + throw new EndOfStreamException(); + return (byte)b; + } + + public sbyte ReadI8 () => (sbyte)ReadU8(); + + public ushort ReadU16 () + { + if (m_input.Read (m_buffer, 0, 2) < 2) + throw new EndOfStreamException(); + return ToU16(); + } + + public short ReadI16 () => (short)ReadU16(); + + public uint ReadU32 () + { + if (m_input.Read (m_buffer, 0, 4) < 4) + throw new EndOfStreamException(); + return ToU32(); + } + + public int ReadI32 () => (int)ReadU32(); + + public byte[] ReadBytes (int length) + { + if (0 == length) + return Array.Empty(); + var buffer = new byte[length]; + if (m_input.Read (buffer, 0, length) < length) + throw new EndOfStreamException(); + return buffer; + } + + public Reader CloneUnless (ByteOrder order) + { + if (this.ByteOrder != order) + return new Reader (this.Source, this.Encoding, order); + else + return this; + } + } +} diff --git a/ArcFormats/Macromedia/ImageBITD.cs b/ArcFormats/Macromedia/ImageBITD.cs index a9c8856d..2212f3be 100644 --- a/ArcFormats/Macromedia/ImageBITD.cs +++ b/ArcFormats/Macromedia/ImageBITD.cs @@ -29,9 +29,10 @@ using System.ComponentModel.Composition; using System.IO; using System.Linq; using System.Windows.Media; +using System.Windows.Media.Imaging; using GameRes.Utility; -namespace GameRes.Formats.Selen +namespace GameRes.Formats.Macromedia { [Export(typeof(ImageFormat))] public class BitdFormat : ImageFormat @@ -202,4 +203,134 @@ namespace GameRes.Formats.Selen } } } + + internal class BitdDecoder : IImageDecoder + { + Stream m_input; + byte[] m_output; + int m_width; + int m_height; + int m_stride; + ImageMetaData m_info; + ImageData m_image; + BitmapPalette m_palette; + + public Stream Source { get => m_input; } + public ImageFormat SourceFormat { get => null; } + public ImageMetaData Info { get => m_info; } + public ImageData Image { get => m_image ?? (m_image = GetImageData()); } + public PixelFormat Format { get; private set; } + + public BitdDecoder (Stream input, ImageMetaData info, BitmapPalette palette) + { + m_input = input; + m_info = info; + m_width = info.iWidth; + m_height = info.iHeight; + m_stride = (m_width * m_info.BPP + 7) / 8; + m_stride = (m_stride + 1) & ~1; + m_output = new byte[m_stride * m_height]; + Format = info.BPP == 4 ? PixelFormats.Indexed4 + : info.BPP == 8 ? PixelFormats.Indexed8 + : info.BPP == 16 ? PixelFormats.Bgr555 + : PixelFormats.Bgr32; + m_palette = palette; + } + + protected ImageData GetImageData () + { + if (Info.BPP <= 8) + Unpack8bpp(); + else + UnpackChannels (Info.BPP / 8); + return ImageData.Create (m_info, Format, m_palette, m_output, m_stride); + } + + void Unpack8bpp () + { + for (int line = 0; line < m_output.Length; line += m_stride) + { + int x = 0; + while (x < m_stride) + { + int b = m_input.ReadByte(); + if (-1 == b) + throw new InvalidFormatException ("Unexpected end of file"); + int count = b; + if (b > 0x7f) + count = (byte)-(sbyte)b; + ++count; + if (x + count > m_stride) + throw new InvalidFormatException(); + if (b > 0x7f) + { + b = m_input.ReadByte(); + if (-1 == b) + throw new InvalidFormatException ("Unexpected end of file"); + for (int i = 0; i < count; ++i) + m_output[line + x++] = (byte)b; + } + else + { + m_input.Read (m_output, line + x, count); + x += count; + } + } + } + } + + public void UnpackChannels (int channels) + { + var scan_line = new byte[m_stride]; + for (int line = 0; line < m_output.Length; line += m_stride) + { + int x = 0; + while (x < m_stride) + { + int b = m_input.ReadByte(); + if (-1 == b) + throw new InvalidFormatException ("Unexpected end of file"); + int count = b; + if (b > 0x7f) + count = (byte)-(sbyte)b; + ++count; + if (x + count > m_stride) + throw new InvalidFormatException(); + if (b > 0x7f) + { + b = m_input.ReadByte(); + if (-1 == b) + throw new InvalidFormatException ("Unexpected end of file"); + for (int i = 0; i < count; ++i) + scan_line[x++] = (byte)b; + } + else + { + m_input.Read (scan_line, x, count); + x += count; + } + } + int dst = line; + for (int i = 0; i < m_width; ++i) + { + for (int src = m_width * (channels - 1); src >= 0; src -= m_width) + m_output[dst++] = scan_line[i + src]; + } + } + } + + #region IDisposable Members + bool m_disposed = false; + + public void Dispose () + { + if (!m_disposed) + { + m_input.Dispose(); + m_disposed = true; + } + GC.SuppressFinalize (this); + } + #endregion + } } diff --git a/ArcFormats/Macromedia/Palettes.cs b/ArcFormats/Macromedia/Palettes.cs new file mode 100644 index 00000000..21b4ed76 --- /dev/null +++ b/ArcFormats/Macromedia/Palettes.cs @@ -0,0 +1,1327 @@ +//! \file Palettes.cs +//! \date 2023 Aug 21 +//! \brief Standard palettes used in 8bpp bitmaps. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Macromedia +{ + internal static class Palettes + { + public static readonly BitmapPalette SystemMac = new BitmapPalette (new Color[] { + Color.FromRgb (0xFF, 0xFF, 0xFF), + Color.FromRgb (0xFF, 0xFF, 0xCC), + Color.FromRgb (0xFF, 0xFF, 0x99), + Color.FromRgb (0xFF, 0xFF, 0x66), + Color.FromRgb (0xFF, 0xFF, 0x33), + Color.FromRgb (0xFF, 0xFF, 0x00), + Color.FromRgb (0xFF, 0xCC, 0xFF), + Color.FromRgb (0xFF, 0xCC, 0xCC), + Color.FromRgb (0xFF, 0xCC, 0x99), + Color.FromRgb (0xFF, 0xCC, 0x66), + Color.FromRgb (0xFF, 0xCC, 0x33), + Color.FromRgb (0xFF, 0xCC, 0x00), + Color.FromRgb (0xFF, 0x99, 0xFF), + Color.FromRgb (0xFF, 0x99, 0xCC), + Color.FromRgb (0xFF, 0x99, 0x99), + Color.FromRgb (0xFF, 0x99, 0x66), + Color.FromRgb (0xFF, 0x99, 0x33), + Color.FromRgb (0xFF, 0x99, 0x00), + Color.FromRgb (0xFF, 0x66, 0xFF), + Color.FromRgb (0xFF, 0x66, 0xCC), + Color.FromRgb (0xFF, 0x66, 0x99), + Color.FromRgb (0xFF, 0x66, 0x66), + Color.FromRgb (0xFF, 0x66, 0x33), + Color.FromRgb (0xFF, 0x66, 0x00), + Color.FromRgb (0xFF, 0x33, 0xFF), + Color.FromRgb (0xFF, 0x33, 0xCC), + Color.FromRgb (0xFF, 0x33, 0x99), + Color.FromRgb (0xFF, 0x33, 0x66), + Color.FromRgb (0xFF, 0x33, 0x33), + Color.FromRgb (0xFF, 0x33, 0x00), + Color.FromRgb (0xFF, 0x00, 0xFF), + Color.FromRgb (0xFF, 0x00, 0xCC), + Color.FromRgb (0xFF, 0x00, 0x99), + Color.FromRgb (0xFF, 0x00, 0x66), + Color.FromRgb (0xFF, 0x00, 0x33), + Color.FromRgb (0xFF, 0x00, 0x00), + Color.FromRgb (0xCC, 0xFF, 0xFF), + Color.FromRgb (0xCC, 0xFF, 0xCC), + Color.FromRgb (0xCC, 0xFF, 0x99), + Color.FromRgb (0xCC, 0xFF, 0x66), + Color.FromRgb (0xCC, 0xFF, 0x33), + Color.FromRgb (0xCC, 0xFF, 0x00), + Color.FromRgb (0xCC, 0xCC, 0xFF), + Color.FromRgb (0xCC, 0xCC, 0xCC), + Color.FromRgb (0xCC, 0xCC, 0x99), + Color.FromRgb (0xCC, 0xCC, 0x66), + Color.FromRgb (0xCC, 0xCC, 0x33), + Color.FromRgb (0xCC, 0xCC, 0x00), + Color.FromRgb (0xCC, 0x99, 0xFF), + Color.FromRgb (0xCC, 0x99, 0xCC), + Color.FromRgb (0xCC, 0x99, 0x99), + Color.FromRgb (0xCC, 0x99, 0x66), + Color.FromRgb (0xCC, 0x99, 0x33), + Color.FromRgb (0xCC, 0x99, 0x00), + Color.FromRgb (0xCC, 0x66, 0xFF), + Color.FromRgb (0xCC, 0x66, 0xCC), + Color.FromRgb (0xCC, 0x66, 0x99), + Color.FromRgb (0xCC, 0x66, 0x66), + Color.FromRgb (0xCC, 0x66, 0x33), + Color.FromRgb (0xCC, 0x66, 0x00), + Color.FromRgb (0xCC, 0x33, 0xFF), + Color.FromRgb (0xCC, 0x33, 0xCC), + Color.FromRgb (0xCC, 0x33, 0x99), + Color.FromRgb (0xCC, 0x33, 0x66), + Color.FromRgb (0xCC, 0x33, 0x33), + Color.FromRgb (0xCC, 0x33, 0x00), + Color.FromRgb (0xCC, 0x00, 0xFF), + Color.FromRgb (0xCC, 0x00, 0xCC), + Color.FromRgb (0xCC, 0x00, 0x99), + Color.FromRgb (0xCC, 0x00, 0x66), + Color.FromRgb (0xCC, 0x00, 0x33), + Color.FromRgb (0xCC, 0x00, 0x00), + Color.FromRgb (0x99, 0xFF, 0xFF), + Color.FromRgb (0x99, 0xFF, 0xCC), + Color.FromRgb (0x99, 0xFF, 0x99), + Color.FromRgb (0x99, 0xFF, 0x66), + Color.FromRgb (0x99, 0xFF, 0x33), + Color.FromRgb (0x99, 0xFF, 0x00), + Color.FromRgb (0x99, 0xCC, 0xFF), + Color.FromRgb (0x99, 0xCC, 0xCC), + Color.FromRgb (0x99, 0xCC, 0x99), + Color.FromRgb (0x99, 0xCC, 0x66), + Color.FromRgb (0x99, 0xCC, 0x33), + Color.FromRgb (0x99, 0xCC, 0x00), + Color.FromRgb (0x99, 0x99, 0xFF), + Color.FromRgb (0x99, 0x99, 0xCC), + Color.FromRgb (0x99, 0x99, 0x99), + Color.FromRgb (0x99, 0x99, 0x66), + Color.FromRgb (0x99, 0x99, 0x33), + Color.FromRgb (0x99, 0x99, 0x00), + Color.FromRgb (0x99, 0x66, 0xFF), + Color.FromRgb (0x99, 0x66, 0xCC), + Color.FromRgb (0x99, 0x66, 0x99), + Color.FromRgb (0x99, 0x66, 0x66), + Color.FromRgb (0x99, 0x66, 0x33), + Color.FromRgb (0x99, 0x66, 0x00), + Color.FromRgb (0x99, 0x33, 0xFF), + Color.FromRgb (0x99, 0x33, 0xCC), + Color.FromRgb (0x99, 0x33, 0x99), + Color.FromRgb (0x99, 0x33, 0x66), + Color.FromRgb (0x99, 0x33, 0x33), + Color.FromRgb (0x99, 0x33, 0x00), + Color.FromRgb (0x99, 0x00, 0xFF), + Color.FromRgb (0x99, 0x00, 0xCC), + Color.FromRgb (0x99, 0x00, 0x99), + Color.FromRgb (0x99, 0x00, 0x66), + Color.FromRgb (0x99, 0x00, 0x33), + Color.FromRgb (0x99, 0x00, 0x00), + Color.FromRgb (0x66, 0xFF, 0xFF), + Color.FromRgb (0x66, 0xFF, 0xCC), + Color.FromRgb (0x66, 0xFF, 0x99), + Color.FromRgb (0x66, 0xFF, 0x66), + Color.FromRgb (0x66, 0xFF, 0x33), + Color.FromRgb (0x66, 0xFF, 0x00), + Color.FromRgb (0x66, 0xCC, 0xFF), + Color.FromRgb (0x66, 0xCC, 0xCC), + Color.FromRgb (0x66, 0xCC, 0x99), + Color.FromRgb (0x66, 0xCC, 0x66), + Color.FromRgb (0x66, 0xCC, 0x33), + Color.FromRgb (0x66, 0xCC, 0x00), + Color.FromRgb (0x66, 0x99, 0xFF), + Color.FromRgb (0x66, 0x99, 0xCC), + Color.FromRgb (0x66, 0x99, 0x99), + Color.FromRgb (0x66, 0x99, 0x66), + Color.FromRgb (0x66, 0x99, 0x33), + Color.FromRgb (0x66, 0x99, 0x00), + Color.FromRgb (0x66, 0x66, 0xFF), + Color.FromRgb (0x66, 0x66, 0xCC), + Color.FromRgb (0x66, 0x66, 0x99), + Color.FromRgb (0x66, 0x66, 0x66), + Color.FromRgb (0x66, 0x66, 0x33), + Color.FromRgb (0x66, 0x66, 0x00), + Color.FromRgb (0x66, 0x33, 0xFF), + Color.FromRgb (0x66, 0x33, 0xCC), + Color.FromRgb (0x66, 0x33, 0x99), + Color.FromRgb (0x66, 0x33, 0x66), + Color.FromRgb (0x66, 0x33, 0x33), + Color.FromRgb (0x66, 0x33, 0x00), + Color.FromRgb (0x66, 0x00, 0xFF), + Color.FromRgb (0x66, 0x00, 0xCC), + Color.FromRgb (0x66, 0x00, 0x99), + Color.FromRgb (0x66, 0x00, 0x66), + Color.FromRgb (0x66, 0x00, 0x33), + Color.FromRgb (0x66, 0x00, 0x00), + Color.FromRgb (0x33, 0xFF, 0xFF), + Color.FromRgb (0x33, 0xFF, 0xCC), + Color.FromRgb (0x33, 0xFF, 0x99), + Color.FromRgb (0x33, 0xFF, 0x66), + Color.FromRgb (0x33, 0xFF, 0x33), + Color.FromRgb (0x33, 0xFF, 0x00), + Color.FromRgb (0x33, 0xCC, 0xFF), + Color.FromRgb (0x33, 0xCC, 0xCC), + Color.FromRgb (0x33, 0xCC, 0x99), + Color.FromRgb (0x33, 0xCC, 0x66), + Color.FromRgb (0x33, 0xCC, 0x33), + Color.FromRgb (0x33, 0xCC, 0x00), + Color.FromRgb (0x33, 0x99, 0xFF), + Color.FromRgb (0x33, 0x99, 0xCC), + Color.FromRgb (0x33, 0x99, 0x99), + Color.FromRgb (0x33, 0x99, 0x66), + Color.FromRgb (0x33, 0x99, 0x33), + Color.FromRgb (0x33, 0x99, 0x00), + Color.FromRgb (0x33, 0x66, 0xFF), + Color.FromRgb (0x33, 0x66, 0xCC), + Color.FromRgb (0x33, 0x66, 0x99), + Color.FromRgb (0x33, 0x66, 0x66), + Color.FromRgb (0x33, 0x66, 0x33), + Color.FromRgb (0x33, 0x66, 0x00), + Color.FromRgb (0x33, 0x33, 0xFF), + Color.FromRgb (0x33, 0x33, 0xCC), + Color.FromRgb (0x33, 0x33, 0x99), + Color.FromRgb (0x33, 0x33, 0x66), + Color.FromRgb (0x33, 0x33, 0x33), + Color.FromRgb (0x33, 0x33, 0x00), + Color.FromRgb (0x33, 0x00, 0xFF), + Color.FromRgb (0x33, 0x00, 0xCC), + Color.FromRgb (0x33, 0x00, 0x99), + Color.FromRgb (0x33, 0x00, 0x66), + Color.FromRgb (0x33, 0x00, 0x33), + Color.FromRgb (0x33, 0x00, 0x00), + Color.FromRgb (0x00, 0xFF, 0xFF), + Color.FromRgb (0x00, 0xFF, 0xCC), + Color.FromRgb (0x00, 0xFF, 0x99), + Color.FromRgb (0x00, 0xFF, 0x66), + Color.FromRgb (0x00, 0xFF, 0x33), + Color.FromRgb (0x00, 0xFF, 0x00), + Color.FromRgb (0x00, 0xCC, 0xFF), + Color.FromRgb (0x00, 0xCC, 0xCC), + Color.FromRgb (0x00, 0xCC, 0x99), + Color.FromRgb (0x00, 0xCC, 0x66), + Color.FromRgb (0x00, 0xCC, 0x33), + Color.FromRgb (0x00, 0xCC, 0x00), + Color.FromRgb (0x00, 0x99, 0xFF), + Color.FromRgb (0x00, 0x99, 0xCC), + Color.FromRgb (0x00, 0x99, 0x99), + Color.FromRgb (0x00, 0x99, 0x66), + Color.FromRgb (0x00, 0x99, 0x33), + Color.FromRgb (0x00, 0x99, 0x00), + Color.FromRgb (0x00, 0x66, 0xFF), + Color.FromRgb (0x00, 0x66, 0xCC), + Color.FromRgb (0x00, 0x66, 0x99), + Color.FromRgb (0x00, 0x66, 0x66), + Color.FromRgb (0x00, 0x66, 0x33), + Color.FromRgb (0x00, 0x66, 0x00), + Color.FromRgb (0x00, 0x33, 0xFF), + Color.FromRgb (0x00, 0x33, 0xCC), + Color.FromRgb (0x00, 0x33, 0x99), + Color.FromRgb (0x00, 0x33, 0x66), + Color.FromRgb (0x00, 0x33, 0x33), + Color.FromRgb (0x00, 0x33, 0x00), + Color.FromRgb (0x00, 0x00, 0xFF), + Color.FromRgb (0x00, 0x00, 0xCC), + Color.FromRgb (0x00, 0x00, 0x99), + Color.FromRgb (0x00, 0x00, 0x66), + Color.FromRgb (0x00, 0x00, 0x33), + Color.FromRgb (0xEE, 0x00, 0x00), + Color.FromRgb (0xDD, 0x00, 0x00), + Color.FromRgb (0xBB, 0x00, 0x00), + Color.FromRgb (0xAA, 0x00, 0x00), + Color.FromRgb (0x88, 0x00, 0x00), + Color.FromRgb (0x77, 0x00, 0x00), + Color.FromRgb (0x55, 0x00, 0x00), + Color.FromRgb (0x44, 0x00, 0x00), + Color.FromRgb (0x22, 0x00, 0x00), + Color.FromRgb (0x11, 0x00, 0x00), + Color.FromRgb (0x00, 0xEE, 0x00), + Color.FromRgb (0x00, 0xDD, 0x00), + Color.FromRgb (0x00, 0xBB, 0x00), + Color.FromRgb (0x00, 0xAA, 0x00), + Color.FromRgb (0x00, 0x88, 0x00), + Color.FromRgb (0x00, 0x77, 0x00), + Color.FromRgb (0x00, 0x55, 0x00), + Color.FromRgb (0x00, 0x44, 0x00), + Color.FromRgb (0x00, 0x22, 0x00), + Color.FromRgb (0x00, 0x11, 0x00), + Color.FromRgb (0x00, 0x00, 0xEE), + Color.FromRgb (0x00, 0x00, 0xDD), + Color.FromRgb (0x00, 0x00, 0xBB), + Color.FromRgb (0x00, 0x00, 0xAA), + Color.FromRgb (0x00, 0x00, 0x88), + Color.FromRgb (0x00, 0x00, 0x77), + Color.FromRgb (0x00, 0x00, 0x55), + Color.FromRgb (0x00, 0x00, 0x44), + Color.FromRgb (0x00, 0x00, 0x22), + Color.FromRgb (0x00, 0x00, 0x11), + Color.FromRgb (0xEE, 0xEE, 0xEE), + Color.FromRgb (0xDD, 0xDD, 0xDD), + Color.FromRgb (0xBB, 0xBB, 0xBB), + Color.FromRgb (0xAA, 0xAA, 0xAA), + Color.FromRgb (0x88, 0x88, 0x88), + Color.FromRgb (0x77, 0x77, 0x77), + Color.FromRgb (0x55, 0x55, 0x55), + Color.FromRgb (0x44, 0x44, 0x44), + Color.FromRgb (0x22, 0x22, 0x22), + Color.FromRgb (0x11, 0x11, 0x11), + Color.FromRgb (0x00, 0x00, 0x00), + }); + public static readonly BitmapPalette SystemWindows = new BitmapPalette (new Color[] { + Color.FromRgb (0xFF, 0xFF, 0xFF), + Color.FromRgb (0x00, 0xFF, 0xFF), + Color.FromRgb (0xFF, 0x00, 0xFF), + Color.FromRgb (0x00, 0x00, 0xFF), + Color.FromRgb (0xFF, 0xFF, 0x00), + Color.FromRgb (0x00, 0xFF, 0x00), + Color.FromRgb (0xFF, 0x00, 0x00), + Color.FromRgb (0x80, 0x80, 0x80), + Color.FromRgb (0xA0, 0xA0, 0xA4), + Color.FromRgb (0xFF, 0xFB, 0xF0), + Color.FromRgb (0x33, 0x33, 0x33), + Color.FromRgb (0x99, 0x66, 0x00), + Color.FromRgb (0x33, 0x66, 0x33), + Color.FromRgb (0x00, 0x33, 0x99), + Color.FromRgb (0xCC, 0x00, 0xFF), + Color.FromRgb (0x88, 0x00, 0x00), + Color.FromRgb (0xFF, 0xCC, 0x66), + Color.FromRgb (0xFF, 0x99, 0xCC), + Color.FromRgb (0xDD, 0xDD, 0xDD), + Color.FromRgb (0xFF, 0x99, 0x00), + Color.FromRgb (0xFF, 0x66, 0xFF), + Color.FromRgb (0xFF, 0x66, 0xCC), + Color.FromRgb (0xFF, 0x66, 0x99), + Color.FromRgb (0xFF, 0x66, 0x66), + Color.FromRgb (0xFF, 0x66, 0x33), + Color.FromRgb (0xFF, 0x66, 0x00), + Color.FromRgb (0xFF, 0x33, 0xFF), + Color.FromRgb (0xFF, 0x33, 0xCC), + Color.FromRgb (0xFF, 0x33, 0x99), + Color.FromRgb (0xFF, 0x33, 0x66), + Color.FromRgb (0xFF, 0x33, 0x33), + Color.FromRgb (0xFF, 0x33, 0x00), + Color.FromRgb (0xFF, 0x00, 0xCC), + Color.FromRgb (0xFF, 0x00, 0x99), + Color.FromRgb (0xFF, 0x00, 0x66), + Color.FromRgb (0xFF, 0x00, 0x33), + Color.FromRgb (0xCC, 0xFF, 0xFF), + Color.FromRgb (0xCC, 0xFF, 0xCC), + Color.FromRgb (0xCC, 0xFF, 0x99), + Color.FromRgb (0xCC, 0xFF, 0x66), + Color.FromRgb (0xCC, 0xFF, 0x33), + Color.FromRgb (0xCC, 0xFF, 0x00), + Color.FromRgb (0xCC, 0xCC, 0xFF), + Color.FromRgb (0xCC, 0xCC, 0xCC), + Color.FromRgb (0xCC, 0xCC, 0x99), + Color.FromRgb (0xCC, 0xCC, 0x66), + Color.FromRgb (0xCC, 0xCC, 0x33), + Color.FromRgb (0xCC, 0xCC, 0x00), + Color.FromRgb (0xCC, 0x99, 0xFF), + Color.FromRgb (0xCC, 0x99, 0xCC), + Color.FromRgb (0xCC, 0x99, 0x99), + Color.FromRgb (0xCC, 0x99, 0x66), + Color.FromRgb (0xCC, 0x99, 0x33), + Color.FromRgb (0xCC, 0x99, 0x00), + Color.FromRgb (0xCC, 0x66, 0xFF), + Color.FromRgb (0xCC, 0x66, 0xCC), + Color.FromRgb (0xCC, 0x66, 0x99), + Color.FromRgb (0xCC, 0x66, 0x66), + Color.FromRgb (0xCC, 0x66, 0x33), + Color.FromRgb (0xCC, 0x66, 0x00), + Color.FromRgb (0xCC, 0x33, 0xFF), + Color.FromRgb (0xCC, 0x33, 0xCC), + Color.FromRgb (0xCC, 0x33, 0x99), + Color.FromRgb (0xCC, 0x33, 0x66), + Color.FromRgb (0xCC, 0x33, 0x33), + Color.FromRgb (0xCC, 0x33, 0x00), + Color.FromRgb (0xD4, 0x08, 0xFF), + Color.FromRgb (0xCC, 0x00, 0xCC), + Color.FromRgb (0xCC, 0x00, 0x99), + Color.FromRgb (0xCC, 0x00, 0x66), + Color.FromRgb (0xCC, 0x00, 0x33), + Color.FromRgb (0xCC, 0x00, 0x00), + Color.FromRgb (0x99, 0xFF, 0xFF), + Color.FromRgb (0x99, 0xFF, 0xCC), + Color.FromRgb (0x99, 0xFF, 0x99), + Color.FromRgb (0x99, 0xFF, 0x66), + Color.FromRgb (0x99, 0xFF, 0x33), + Color.FromRgb (0x99, 0xFF, 0x00), + Color.FromRgb (0x99, 0xCC, 0xFF), + Color.FromRgb (0x99, 0xCC, 0xCC), + Color.FromRgb (0x99, 0xCC, 0x99), + Color.FromRgb (0x99, 0xCC, 0x66), + Color.FromRgb (0x99, 0xCC, 0x33), + Color.FromRgb (0x99, 0xCC, 0x00), + Color.FromRgb (0x99, 0x99, 0xFF), + Color.FromRgb (0x99, 0x99, 0xCC), + Color.FromRgb (0x99, 0x99, 0x99), + Color.FromRgb (0x99, 0x99, 0x66), + Color.FromRgb (0x99, 0x99, 0x33), + Color.FromRgb (0x99, 0x99, 0x00), + Color.FromRgb (0x99, 0x66, 0xFF), + Color.FromRgb (0x99, 0x66, 0xCC), + Color.FromRgb (0x99, 0x66, 0x99), + Color.FromRgb (0x99, 0x66, 0x66), + Color.FromRgb (0x99, 0x66, 0x33), + Color.FromRgb (0xA1, 0x66, 0x00), + Color.FromRgb (0x99, 0x33, 0xFF), + Color.FromRgb (0x99, 0x33, 0xCC), + Color.FromRgb (0x99, 0x33, 0x99), + Color.FromRgb (0x99, 0x33, 0x66), + Color.FromRgb (0x99, 0x33, 0x33), + Color.FromRgb (0x99, 0x33, 0x00), + Color.FromRgb (0x99, 0x00, 0xFF), + Color.FromRgb (0x99, 0x00, 0xCC), + Color.FromRgb (0x99, 0x00, 0x99), + Color.FromRgb (0x99, 0x00, 0x66), + Color.FromRgb (0x99, 0x00, 0x33), + Color.FromRgb (0x99, 0x00, 0x00), + Color.FromRgb (0x66, 0xFF, 0xFF), + Color.FromRgb (0x66, 0xFF, 0xCC), + Color.FromRgb (0x66, 0xFF, 0x99), + Color.FromRgb (0x66, 0xFF, 0x66), + Color.FromRgb (0x66, 0xFF, 0x33), + Color.FromRgb (0x66, 0xFF, 0x00), + Color.FromRgb (0x66, 0xCC, 0xFF), + Color.FromRgb (0x66, 0xCC, 0xCC), + Color.FromRgb (0x66, 0xCC, 0x99), + Color.FromRgb (0x66, 0xCC, 0x66), + Color.FromRgb (0x66, 0xCC, 0x33), + Color.FromRgb (0x66, 0xCC, 0x00), + Color.FromRgb (0x66, 0x99, 0xFF), + Color.FromRgb (0x66, 0x99, 0xCC), + Color.FromRgb (0x66, 0x99, 0x99), + Color.FromRgb (0x66, 0x99, 0x66), + Color.FromRgb (0x66, 0x99, 0x33), + Color.FromRgb (0x66, 0x99, 0x00), + Color.FromRgb (0x66, 0x66, 0xFF), + Color.FromRgb (0x66, 0x66, 0xCC), + Color.FromRgb (0x66, 0x66, 0x99), + Color.FromRgb (0x66, 0x66, 0x66), + Color.FromRgb (0x66, 0x66, 0x33), + Color.FromRgb (0x66, 0x66, 0x00), + Color.FromRgb (0x66, 0x33, 0xFF), + Color.FromRgb (0x66, 0x33, 0xCC), + Color.FromRgb (0x66, 0x33, 0x99), + Color.FromRgb (0x66, 0x33, 0x66), + Color.FromRgb (0x66, 0x33, 0x33), + Color.FromRgb (0x66, 0x33, 0x00), + Color.FromRgb (0x66, 0x00, 0xFF), + Color.FromRgb (0x66, 0x00, 0xCC), + Color.FromRgb (0x66, 0x00, 0x99), + Color.FromRgb (0x66, 0x00, 0x66), + Color.FromRgb (0x66, 0x00, 0x33), + Color.FromRgb (0x66, 0x00, 0x00), + Color.FromRgb (0x33, 0xFF, 0xFF), + Color.FromRgb (0x33, 0xFF, 0xCC), + Color.FromRgb (0x33, 0xFF, 0x99), + Color.FromRgb (0x33, 0xFF, 0x66), + Color.FromRgb (0x33, 0xFF, 0x33), + Color.FromRgb (0x33, 0xFF, 0x00), + Color.FromRgb (0x33, 0xCC, 0xFF), + Color.FromRgb (0x33, 0xCC, 0xCC), + Color.FromRgb (0x33, 0xCC, 0x99), + Color.FromRgb (0x33, 0xCC, 0x66), + Color.FromRgb (0x33, 0xCC, 0x33), + Color.FromRgb (0x33, 0xCC, 0x00), + Color.FromRgb (0x33, 0x99, 0xFF), + Color.FromRgb (0x33, 0x99, 0xCC), + Color.FromRgb (0x33, 0x99, 0x99), + Color.FromRgb (0x33, 0x99, 0x66), + Color.FromRgb (0x33, 0x99, 0x33), + Color.FromRgb (0x33, 0x99, 0x00), + Color.FromRgb (0x33, 0x66, 0xFF), + Color.FromRgb (0x33, 0x66, 0xCC), + Color.FromRgb (0x33, 0x66, 0x99), + Color.FromRgb (0x33, 0x66, 0x66), + Color.FromRgb (0x33, 0x6E, 0x33), + Color.FromRgb (0x33, 0x66, 0x00), + Color.FromRgb (0x33, 0x33, 0xFF), + Color.FromRgb (0x33, 0x33, 0xCC), + Color.FromRgb (0x33, 0x33, 0x99), + Color.FromRgb (0x33, 0x33, 0x66), + Color.FromRgb (0x33, 0x33, 0x3B), + Color.FromRgb (0x33, 0x33, 0x00), + Color.FromRgb (0x33, 0x00, 0xFF), + Color.FromRgb (0x33, 0x00, 0xCC), + Color.FromRgb (0x33, 0x00, 0x99), + Color.FromRgb (0x33, 0x00, 0x66), + Color.FromRgb (0x33, 0x00, 0x33), + Color.FromRgb (0x33, 0x00, 0x00), + Color.FromRgb (0x00, 0xFF, 0xCC), + Color.FromRgb (0x00, 0xFF, 0x99), + Color.FromRgb (0x00, 0xFF, 0x66), + Color.FromRgb (0x00, 0xFF, 0x33), + Color.FromRgb (0x00, 0xCC, 0xFF), + Color.FromRgb (0x00, 0xCC, 0xCC), + Color.FromRgb (0x00, 0xCC, 0x99), + Color.FromRgb (0x00, 0xCC, 0x66), + Color.FromRgb (0x00, 0xCC, 0x33), + Color.FromRgb (0x00, 0xCC, 0x00), + Color.FromRgb (0x00, 0x99, 0xFF), + Color.FromRgb (0x00, 0x99, 0xCC), + Color.FromRgb (0x00, 0x99, 0x99), + Color.FromRgb (0x00, 0x99, 0x66), + Color.FromRgb (0x00, 0x99, 0x33), + Color.FromRgb (0x00, 0x99, 0x00), + Color.FromRgb (0x00, 0x66, 0xFF), + Color.FromRgb (0x00, 0x66, 0xCC), + Color.FromRgb (0x00, 0x66, 0x99), + Color.FromRgb (0x00, 0x66, 0x66), + Color.FromRgb (0x00, 0x66, 0x33), + Color.FromRgb (0x00, 0x66, 0x00), + Color.FromRgb (0x00, 0x33, 0xFF), + Color.FromRgb (0x00, 0x33, 0xCC), + Color.FromRgb (0x00, 0x33, 0xA1), + Color.FromRgb (0x00, 0x33, 0x66), + Color.FromRgb (0x00, 0x33, 0x33), + Color.FromRgb (0x00, 0x33, 0x00), + Color.FromRgb (0x00, 0x00, 0xCC), + Color.FromRgb (0x00, 0x00, 0x99), + Color.FromRgb (0x00, 0x00, 0x66), + Color.FromRgb (0x00, 0x00, 0x33), + Color.FromRgb (0xEE, 0x00, 0x00), + Color.FromRgb (0xDD, 0x00, 0x00), + Color.FromRgb (0xAA, 0x00, 0x00), + Color.FromRgb (0x90, 0x00, 0x00), + Color.FromRgb (0x77, 0x00, 0x00), + Color.FromRgb (0x55, 0x00, 0x00), + Color.FromRgb (0x44, 0x00, 0x00), + Color.FromRgb (0x22, 0x00, 0x00), + Color.FromRgb (0x11, 0x00, 0x00), + Color.FromRgb (0x00, 0xEE, 0x00), + Color.FromRgb (0x00, 0xDD, 0x00), + Color.FromRgb (0x00, 0xAA, 0x00), + Color.FromRgb (0x00, 0x88, 0x00), + Color.FromRgb (0x00, 0x77, 0x00), + Color.FromRgb (0x00, 0x55, 0x00), + Color.FromRgb (0x00, 0x44, 0x00), + Color.FromRgb (0x00, 0x22, 0x00), + Color.FromRgb (0x00, 0x11, 0x00), + Color.FromRgb (0x00, 0x00, 0xEE), + Color.FromRgb (0x00, 0x00, 0xDD), + Color.FromRgb (0x00, 0x00, 0xAA), + Color.FromRgb (0x00, 0x00, 0x88), + Color.FromRgb (0x00, 0x00, 0x77), + Color.FromRgb (0x00, 0x00, 0x55), + Color.FromRgb (0x00, 0x00, 0x44), + Color.FromRgb (0x00, 0x00, 0x22), + Color.FromRgb (0x00, 0x00, 0x11), + Color.FromRgb (0x22, 0x22, 0x30), + Color.FromRgb (0xFF, 0x99, 0x99), + Color.FromRgb (0xFF, 0xCC, 0xFF), + Color.FromRgb (0x99, 0xD4, 0xFF), + Color.FromRgb (0x99, 0xD4, 0x99), + Color.FromRgb (0xFF, 0xFF, 0x99), + Color.FromRgb (0xF0, 0xF0, 0xF0), + Color.FromRgb (0xA4, 0xC8, 0xF0), + Color.FromRgb (0xC0, 0xDC, 0xC0), + Color.FromRgb (0xC0, 0xC0, 0xC0), + Color.FromRgb (0x00, 0x80, 0x80), + Color.FromRgb (0x80, 0x00, 0x80), + Color.FromRgb (0x00, 0x00, 0x80), + Color.FromRgb (0x80, 0x80, 0x00), + Color.FromRgb (0x00, 0x80, 0x00), + Color.FromRgb (0x80, 0x00, 0x00), + Color.FromRgb (0x00, 0x00, 0x00), + }); + + public static readonly BitmapPalette WindowsDirector4 = new BitmapPalette (new Color[] { + Color.FromRgb (0xFF, 0xFF, 0xFF), + Color.FromRgb (0x00, 0xFF, 0xFF), + Color.FromRgb (0xFF, 0x00, 0xFF), + Color.FromRgb (0x00, 0x00, 0xFF), + Color.FromRgb (0xFF, 0xFF, 0x00), + Color.FromRgb (0x00, 0xFF, 0x00), + Color.FromRgb (0xFF, 0x00, 0x00), + Color.FromRgb (0x80, 0x80, 0x80), + Color.FromRgb (0xA0, 0xA0, 0xA4), + Color.FromRgb (0xFF, 0xFB, 0xF0), + Color.FromRgb (0x33, 0x33, 0x33), + Color.FromRgb (0x99, 0x66, 0x00), + Color.FromRgb (0x33, 0x66, 0x33), + Color.FromRgb (0x00, 0x33, 0x99), + Color.FromRgb (0xCC, 0x00, 0xFF), + Color.FromRgb (0x88, 0x00, 0x00), + Color.FromRgb (0xFF, 0xCC, 0x66), + Color.FromRgb (0xFF, 0x99, 0xCC), + Color.FromRgb (0xDD, 0xDD, 0xDD), + Color.FromRgb (0xFF, 0x99, 0x00), + Color.FromRgb (0xFF, 0x66, 0xFF), + Color.FromRgb (0xFF, 0x66, 0xCC), + Color.FromRgb (0xFF, 0x66, 0x99), + Color.FromRgb (0xFF, 0x66, 0x66), + Color.FromRgb (0xFF, 0x66, 0x33), + Color.FromRgb (0xFF, 0x66, 0x00), + Color.FromRgb (0xFF, 0x33, 0xFF), + Color.FromRgb (0xFF, 0x33, 0xCC), + Color.FromRgb (0xFF, 0x33, 0x99), + Color.FromRgb (0xFF, 0x33, 0x66), + Color.FromRgb (0xFF, 0x33, 0x33), + Color.FromRgb (0xFF, 0x33, 0x00), + Color.FromRgb (0xFF, 0x00, 0xCC), + Color.FromRgb (0xFF, 0x00, 0x99), + Color.FromRgb (0xFF, 0x00, 0x66), + Color.FromRgb (0xFF, 0x00, 0x33), + Color.FromRgb (0xCC, 0xFF, 0xFF), + Color.FromRgb (0xCC, 0xFF, 0xCC), + Color.FromRgb (0xCC, 0xFF, 0x99), + Color.FromRgb (0xCC, 0xFF, 0x66), + Color.FromRgb (0xCC, 0xFF, 0x33), + Color.FromRgb (0xCC, 0xFF, 0x00), + Color.FromRgb (0xCC, 0xCC, 0xFF), + Color.FromRgb (0xCC, 0xCC, 0xCC), + Color.FromRgb (0xCC, 0xCC, 0x99), + Color.FromRgb (0xCC, 0xCC, 0x66), + Color.FromRgb (0xCC, 0xCC, 0x33), + Color.FromRgb (0xCC, 0xCC, 0x00), + Color.FromRgb (0xCC, 0x99, 0xFF), + Color.FromRgb (0xCC, 0x99, 0xCC), + Color.FromRgb (0xCC, 0x99, 0x99), + Color.FromRgb (0xCC, 0x99, 0x66), + Color.FromRgb (0xCC, 0x99, 0x33), + Color.FromRgb (0xCC, 0x99, 0x00), + Color.FromRgb (0xCC, 0x66, 0xFF), + Color.FromRgb (0xCC, 0x66, 0xCC), + Color.FromRgb (0xCC, 0x66, 0x99), + Color.FromRgb (0xCC, 0x66, 0x66), + Color.FromRgb (0xCC, 0x66, 0x33), + Color.FromRgb (0xCC, 0x66, 0x00), + Color.FromRgb (0xCC, 0x33, 0xFF), + Color.FromRgb (0xCC, 0x33, 0xCC), + Color.FromRgb (0xCC, 0x33, 0x99), + Color.FromRgb (0xCC, 0x33, 0x66), + Color.FromRgb (0xCC, 0x33, 0x33), + Color.FromRgb (0xCC, 0x33, 0x00), + Color.FromRgb (0xD4, 0x08, 0xFF), + Color.FromRgb (0xCC, 0x00, 0xCC), + Color.FromRgb (0xCC, 0x00, 0x99), + Color.FromRgb (0xCC, 0x00, 0x66), + Color.FromRgb (0xCC, 0x00, 0x33), + Color.FromRgb (0xCC, 0x00, 0x00), + Color.FromRgb (0x99, 0xFF, 0xFF), + Color.FromRgb (0x99, 0xFF, 0xCC), + Color.FromRgb (0x99, 0xFF, 0x99), + Color.FromRgb (0x99, 0xFF, 0x66), + Color.FromRgb (0x99, 0xFF, 0x33), + Color.FromRgb (0x99, 0xFF, 0x00), + Color.FromRgb (0x99, 0xCC, 0xFF), + Color.FromRgb (0x99, 0xCC, 0xCC), + Color.FromRgb (0x99, 0xCC, 0x99), + Color.FromRgb (0x99, 0xCC, 0x66), + Color.FromRgb (0x99, 0xCC, 0x33), + Color.FromRgb (0x99, 0xCC, 0x00), + Color.FromRgb (0x99, 0x99, 0xFF), + Color.FromRgb (0x99, 0x99, 0xCC), + Color.FromRgb (0x99, 0x99, 0x99), + Color.FromRgb (0x99, 0x99, 0x66), + Color.FromRgb (0x99, 0x99, 0x33), + Color.FromRgb (0x99, 0x99, 0x00), + Color.FromRgb (0x99, 0x66, 0xFF), + Color.FromRgb (0x99, 0x66, 0xCC), + Color.FromRgb (0x99, 0x66, 0x99), + Color.FromRgb (0x99, 0x66, 0x66), + Color.FromRgb (0x99, 0x66, 0x33), + Color.FromRgb (0xA1, 0x66, 0x00), + Color.FromRgb (0x99, 0x33, 0xFF), + Color.FromRgb (0x99, 0x33, 0xCC), + Color.FromRgb (0x99, 0x33, 0x99), + Color.FromRgb (0x99, 0x33, 0x66), + Color.FromRgb (0x99, 0x33, 0x33), + Color.FromRgb (0x99, 0x33, 0x00), + Color.FromRgb (0x99, 0x00, 0xFF), + Color.FromRgb (0x99, 0x00, 0xCC), + Color.FromRgb (0x99, 0x00, 0x99), + Color.FromRgb (0x99, 0x00, 0x66), + Color.FromRgb (0x99, 0x00, 0x33), + Color.FromRgb (0x99, 0x00, 0x00), + Color.FromRgb (0x66, 0xFF, 0xFF), + Color.FromRgb (0x66, 0xFF, 0xCC), + Color.FromRgb (0x66, 0xFF, 0x99), + Color.FromRgb (0x66, 0xFF, 0x66), + Color.FromRgb (0x66, 0xFF, 0x33), + Color.FromRgb (0x66, 0xFF, 0x00), + Color.FromRgb (0x66, 0xCC, 0xFF), + Color.FromRgb (0x66, 0xCC, 0xCC), + Color.FromRgb (0x66, 0xCC, 0x99), + Color.FromRgb (0x66, 0xCC, 0x66), + Color.FromRgb (0x66, 0xCC, 0x33), + Color.FromRgb (0x66, 0xCC, 0x00), + Color.FromRgb (0x66, 0x99, 0xFF), + Color.FromRgb (0x66, 0x99, 0xCC), + Color.FromRgb (0x66, 0x99, 0x99), + Color.FromRgb (0x66, 0x99, 0x66), + Color.FromRgb (0x66, 0x99, 0x33), + Color.FromRgb (0x66, 0x99, 0x00), + Color.FromRgb (0x66, 0x66, 0xFF), + Color.FromRgb (0x66, 0x66, 0xCC), + Color.FromRgb (0x66, 0x66, 0x99), + Color.FromRgb (0x66, 0x66, 0x66), + Color.FromRgb (0x66, 0x66, 0x33), + Color.FromRgb (0x66, 0x66, 0x00), + Color.FromRgb (0x66, 0x33, 0xFF), + Color.FromRgb (0x66, 0x33, 0xCC), + Color.FromRgb (0x66, 0x33, 0x99), + Color.FromRgb (0x66, 0x33, 0x66), + Color.FromRgb (0x66, 0x33, 0x33), + Color.FromRgb (0x66, 0x33, 0x00), + Color.FromRgb (0x66, 0x00, 0xFF), + Color.FromRgb (0x66, 0x00, 0xCC), + Color.FromRgb (0x66, 0x00, 0x99), + Color.FromRgb (0x66, 0x00, 0x66), + Color.FromRgb (0x66, 0x00, 0x33), + Color.FromRgb (0x66, 0x00, 0x00), + Color.FromRgb (0x33, 0xFF, 0xFF), + Color.FromRgb (0x33, 0xFF, 0xCC), + Color.FromRgb (0x33, 0xFF, 0x99), + Color.FromRgb (0x33, 0xFF, 0x66), + Color.FromRgb (0x33, 0xFF, 0x33), + Color.FromRgb (0x33, 0xFF, 0x00), + Color.FromRgb (0x33, 0xCC, 0xFF), + Color.FromRgb (0x33, 0xCC, 0xCC), + Color.FromRgb (0x33, 0xCC, 0x99), + Color.FromRgb (0x33, 0xCC, 0x66), + Color.FromRgb (0x33, 0xCC, 0x33), + Color.FromRgb (0x33, 0xCC, 0x00), + Color.FromRgb (0x33, 0x99, 0xFF), + Color.FromRgb (0x33, 0x99, 0xCC), + Color.FromRgb (0x33, 0x99, 0x99), + Color.FromRgb (0x33, 0x99, 0x66), + Color.FromRgb (0x33, 0x99, 0x33), + Color.FromRgb (0x33, 0x99, 0x00), + Color.FromRgb (0x33, 0x66, 0xFF), + Color.FromRgb (0x33, 0x66, 0xCC), + Color.FromRgb (0x33, 0x66, 0x99), + Color.FromRgb (0x33, 0x66, 0x66), + Color.FromRgb (0x33, 0x6E, 0x33), + Color.FromRgb (0x33, 0x66, 0x00), + Color.FromRgb (0x33, 0x33, 0xFF), + Color.FromRgb (0x33, 0x33, 0xCC), + Color.FromRgb (0x33, 0x33, 0x99), + Color.FromRgb (0x33, 0x33, 0x66), + Color.FromRgb (0x33, 0x33, 0x3B), + Color.FromRgb (0x33, 0x33, 0x00), + Color.FromRgb (0x33, 0x00, 0xFF), + Color.FromRgb (0x33, 0x00, 0xCC), + Color.FromRgb (0x33, 0x00, 0x99), + Color.FromRgb (0x33, 0x00, 0x66), + Color.FromRgb (0x33, 0x00, 0x33), + Color.FromRgb (0x33, 0x00, 0x00), + Color.FromRgb (0x00, 0xFF, 0xCC), + Color.FromRgb (0x00, 0xFF, 0x99), + Color.FromRgb (0x00, 0xFF, 0x66), + Color.FromRgb (0x00, 0xFF, 0x33), + Color.FromRgb (0x00, 0xCC, 0xFF), + Color.FromRgb (0x00, 0xCC, 0xCC), + Color.FromRgb (0x00, 0xCC, 0x99), + Color.FromRgb (0x00, 0xCC, 0x66), + Color.FromRgb (0x00, 0xCC, 0x33), + Color.FromRgb (0x00, 0xCC, 0x00), + Color.FromRgb (0x00, 0x99, 0xFF), + Color.FromRgb (0x00, 0x99, 0xCC), + Color.FromRgb (0x00, 0x99, 0x99), + Color.FromRgb (0x00, 0x99, 0x66), + Color.FromRgb (0x00, 0x99, 0x33), + Color.FromRgb (0x00, 0x99, 0x00), + Color.FromRgb (0x00, 0x66, 0xFF), + Color.FromRgb (0x00, 0x66, 0xCC), + Color.FromRgb (0x00, 0x66, 0x99), + Color.FromRgb (0x00, 0x66, 0x66), + Color.FromRgb (0x00, 0x66, 0x33), + Color.FromRgb (0x00, 0x66, 0x00), + Color.FromRgb (0x00, 0x33, 0xFF), + Color.FromRgb (0x00, 0x33, 0xCC), + Color.FromRgb (0x00, 0x33, 0xA1), + Color.FromRgb (0x00, 0x33, 0x66), + Color.FromRgb (0x00, 0x33, 0x33), + Color.FromRgb (0x00, 0x33, 0x00), + Color.FromRgb (0x00, 0x00, 0xCC), + Color.FromRgb (0x00, 0x00, 0x99), + Color.FromRgb (0x00, 0x00, 0x66), + Color.FromRgb (0x00, 0x00, 0x33), + Color.FromRgb (0xEE, 0x00, 0x00), + Color.FromRgb (0xDD, 0x00, 0x00), + Color.FromRgb (0xAA, 0x00, 0x00), + Color.FromRgb (0x90, 0x00, 0x00), + Color.FromRgb (0x77, 0x00, 0x00), + Color.FromRgb (0x55, 0x00, 0x00), + Color.FromRgb (0x44, 0x00, 0x00), + Color.FromRgb (0x22, 0x00, 0x00), + Color.FromRgb (0x11, 0x00, 0x00), + Color.FromRgb (0x00, 0xEE, 0x00), + Color.FromRgb (0x00, 0xDD, 0x00), + Color.FromRgb (0x00, 0xAA, 0x00), + Color.FromRgb (0x00, 0x88, 0x00), + Color.FromRgb (0x00, 0x77, 0x00), + Color.FromRgb (0x00, 0x55, 0x00), + Color.FromRgb (0x00, 0x44, 0x00), + Color.FromRgb (0x00, 0x22, 0x00), + Color.FromRgb (0x00, 0x11, 0x00), + Color.FromRgb (0x00, 0x00, 0xEE), + Color.FromRgb (0x00, 0x00, 0xDD), + Color.FromRgb (0x00, 0x00, 0xAA), + Color.FromRgb (0x00, 0x00, 0x88), + Color.FromRgb (0x00, 0x00, 0x77), + Color.FromRgb (0x00, 0x00, 0x55), + Color.FromRgb (0x00, 0x00, 0x44), + Color.FromRgb (0x00, 0x00, 0x22), + Color.FromRgb (0x00, 0x00, 0x11), + Color.FromRgb (0x22, 0x22, 0x30), + Color.FromRgb (0xFF, 0x99, 0x99), + Color.FromRgb (0xFF, 0xCC, 0xFF), + Color.FromRgb (0x99, 0xD4, 0xFF), + Color.FromRgb (0x99, 0xD4, 0x99), + Color.FromRgb (0xFF, 0xFF, 0x99), + Color.FromRgb (0xF0, 0xF0, 0xF0), + Color.FromRgb (0xA4, 0xC8, 0xF0), + Color.FromRgb (0xC0, 0xDC, 0xC0), + Color.FromRgb (0xC0, 0xC0, 0xC0), + Color.FromRgb (0x00, 0xBF, 0xBF), + Color.FromRgb (0xBF, 0x00, 0xBF), + Color.FromRgb (0x00, 0x00, 0xBF), + Color.FromRgb (0xBF, 0xBF, 0x00), + Color.FromRgb (0x00, 0xBF, 0x00), + Color.FromRgb (0xBF, 0x00, 0x00), + Color.FromRgb (0x00, 0x00, 0x00), + }); + + public static readonly BitmapPalette Rainbow = new BitmapPalette (new Color[] { + Color.FromRgb (0xFF, 0xFF, 0xFF), + Color.FromRgb (0x00, 0x69, 0xFF), + Color.FromRgb (0x00, 0x63, 0xFF), + Color.FromRgb (0x00, 0x5D, 0xFF), + Color.FromRgb (0x00, 0x56, 0xFF), + Color.FromRgb (0x00, 0x50, 0xFF), + Color.FromRgb (0x00, 0x4A, 0xFF), + Color.FromRgb (0x00, 0x43, 0xFF), + Color.FromRgb (0x00, 0x3D, 0xFF), + Color.FromRgb (0x00, 0x36, 0xFF), + Color.FromRgb (0x00, 0x30, 0xFF), + Color.FromRgb (0x00, 0x2A, 0xFF), + Color.FromRgb (0x00, 0x23, 0xFF), + Color.FromRgb (0x00, 0x1D, 0xFF), + Color.FromRgb (0x00, 0x16, 0xFF), + Color.FromRgb (0x00, 0x10, 0xFF), + Color.FromRgb (0x00, 0x0A, 0xFF), + Color.FromRgb (0x00, 0x03, 0xFF), + Color.FromRgb (0x06, 0x00, 0xFF), + Color.FromRgb (0x0C, 0x00, 0xFF), + Color.FromRgb (0x13, 0x00, 0xFF), + Color.FromRgb (0x19, 0x00, 0xFF), + Color.FromRgb (0x1F, 0x00, 0xFF), + Color.FromRgb (0x26, 0x00, 0xFF), + Color.FromRgb (0x2C, 0x00, 0xFF), + Color.FromRgb (0x33, 0x00, 0xFF), + Color.FromRgb (0x39, 0x00, 0xFF), + Color.FromRgb (0x3F, 0x00, 0xFF), + Color.FromRgb (0x46, 0x00, 0xFF), + Color.FromRgb (0x4C, 0x00, 0xFF), + Color.FromRgb (0x53, 0x00, 0xFF), + Color.FromRgb (0x59, 0x00, 0xFF), + Color.FromRgb (0x5F, 0x00, 0xFF), + Color.FromRgb (0x66, 0x00, 0xFF), + Color.FromRgb (0x6C, 0x00, 0xFF), + Color.FromRgb (0x72, 0x00, 0xFF), + Color.FromRgb (0x79, 0x00, 0xFF), + Color.FromRgb (0x7F, 0x00, 0xFF), + Color.FromRgb (0x86, 0x00, 0xFF), + Color.FromRgb (0x8C, 0x00, 0xFF), + Color.FromRgb (0x92, 0x00, 0xFF), + Color.FromRgb (0x99, 0x00, 0xFF), + Color.FromRgb (0x9F, 0x00, 0xFF), + Color.FromRgb (0xA5, 0x00, 0xFF), + Color.FromRgb (0xAC, 0x00, 0xFF), + Color.FromRgb (0xB2, 0x00, 0xFF), + Color.FromRgb (0xB9, 0x00, 0xFF), + Color.FromRgb (0xBF, 0x00, 0xFF), + Color.FromRgb (0xC6, 0x00, 0xFF), + Color.FromRgb (0xCC, 0x00, 0xFF), + Color.FromRgb (0xD2, 0x00, 0xFF), + Color.FromRgb (0xD9, 0x00, 0xFF), + Color.FromRgb (0xDF, 0x00, 0xFF), + Color.FromRgb (0xE5, 0x00, 0xFF), + Color.FromRgb (0xEC, 0x00, 0xFF), + Color.FromRgb (0xF2, 0x00, 0xFF), + Color.FromRgb (0xF8, 0x00, 0xFF), + Color.FromRgb (0xFF, 0x00, 0xFF), + Color.FromRgb (0xFF, 0x00, 0xF8), + Color.FromRgb (0xFF, 0x00, 0xF2), + Color.FromRgb (0xFF, 0x00, 0xEB), + Color.FromRgb (0xFF, 0x00, 0xE5), + Color.FromRgb (0xFF, 0x00, 0xDF), + Color.FromRgb (0xFF, 0x00, 0xD8), + Color.FromRgb (0xFF, 0x00, 0xD2), + Color.FromRgb (0xFF, 0x00, 0xCB), + Color.FromRgb (0xFF, 0x00, 0xC5), + Color.FromRgb (0xFF, 0x00, 0xBF), + Color.FromRgb (0xFF, 0x00, 0xB8), + Color.FromRgb (0xFF, 0x00, 0xB2), + Color.FromRgb (0xFF, 0x00, 0xAB), + Color.FromRgb (0xFF, 0x00, 0xA5), + Color.FromRgb (0xFF, 0x00, 0x9F), + Color.FromRgb (0xFF, 0x00, 0x98), + Color.FromRgb (0xFF, 0x00, 0x92), + Color.FromRgb (0xFF, 0x00, 0x8B), + Color.FromRgb (0xFF, 0x00, 0x85), + Color.FromRgb (0xFF, 0x00, 0x7F), + Color.FromRgb (0xFF, 0x00, 0x78), + Color.FromRgb (0xFF, 0x00, 0x72), + Color.FromRgb (0xFF, 0x00, 0x6B), + Color.FromRgb (0xFF, 0x00, 0x65), + Color.FromRgb (0xFF, 0x00, 0x5F), + Color.FromRgb (0xFF, 0x00, 0x58), + Color.FromRgb (0xFF, 0x00, 0x52), + Color.FromRgb (0xFF, 0x00, 0x4B), + Color.FromRgb (0xFF, 0x00, 0x45), + Color.FromRgb (0xFF, 0x00, 0x3F), + Color.FromRgb (0xFF, 0x00, 0x38), + Color.FromRgb (0xFF, 0x00, 0x32), + Color.FromRgb (0xFF, 0x00, 0x2B), + Color.FromRgb (0xFF, 0x00, 0x25), + Color.FromRgb (0xFF, 0x00, 0x1F), + Color.FromRgb (0xFF, 0x00, 0x18), + Color.FromRgb (0xFF, 0x00, 0x12), + Color.FromRgb (0xFF, 0x00, 0x0B), + Color.FromRgb (0xFF, 0x00, 0x06), + Color.FromRgb (0xFF, 0x00, 0x00), + Color.FromRgb (0xFF, 0x06, 0x00), + Color.FromRgb (0xFF, 0x0C, 0x00), + Color.FromRgb (0xFF, 0x13, 0x00), + Color.FromRgb (0xFF, 0x19, 0x00), + Color.FromRgb (0xFF, 0x1F, 0x00), + Color.FromRgb (0xFF, 0x26, 0x00), + Color.FromRgb (0xFF, 0x2C, 0x00), + Color.FromRgb (0xFF, 0x33, 0x00), + Color.FromRgb (0xFF, 0x39, 0x00), + Color.FromRgb (0xFF, 0x3F, 0x00), + Color.FromRgb (0xFF, 0x46, 0x00), + Color.FromRgb (0xFF, 0x4C, 0x00), + Color.FromRgb (0xFF, 0x53, 0x00), + Color.FromRgb (0xFF, 0x59, 0x00), + Color.FromRgb (0xFF, 0x5F, 0x00), + Color.FromRgb (0xFF, 0x66, 0x00), + Color.FromRgb (0xFF, 0x6C, 0x00), + Color.FromRgb (0xFF, 0x73, 0x00), + Color.FromRgb (0xFF, 0x79, 0x00), + Color.FromRgb (0xFF, 0x7F, 0x00), + Color.FromRgb (0xFF, 0x86, 0x00), + Color.FromRgb (0xFF, 0x8C, 0x00), + Color.FromRgb (0xFF, 0x93, 0x00), + Color.FromRgb (0xFF, 0x99, 0x00), + Color.FromRgb (0xFF, 0x9F, 0x00), + Color.FromRgb (0xFF, 0xA6, 0x00), + Color.FromRgb (0xFF, 0xAC, 0x00), + Color.FromRgb (0xFF, 0xB3, 0x00), + Color.FromRgb (0xFF, 0xB9, 0x00), + Color.FromRgb (0xFF, 0xBF, 0x00), + Color.FromRgb (0xFF, 0xC6, 0x00), + Color.FromRgb (0xFF, 0xCC, 0x00), + Color.FromRgb (0xFF, 0xD3, 0x00), + Color.FromRgb (0xFF, 0xD9, 0x00), + Color.FromRgb (0xFF, 0xDF, 0x00), + Color.FromRgb (0xFF, 0xE6, 0x00), + Color.FromRgb (0xFF, 0xEC, 0x00), + Color.FromRgb (0xFF, 0xF3, 0x00), + Color.FromRgb (0xFF, 0xF8, 0x00), + Color.FromRgb (0xFF, 0xFF, 0x00), + Color.FromRgb (0xF8, 0xFF, 0x00), + Color.FromRgb (0xF2, 0xFF, 0x00), + Color.FromRgb (0xEB, 0xFF, 0x00), + Color.FromRgb (0xE5, 0xFF, 0x00), + Color.FromRgb (0xDF, 0xFF, 0x00), + Color.FromRgb (0xD8, 0xFF, 0x00), + Color.FromRgb (0xD2, 0xFF, 0x00), + Color.FromRgb (0xCC, 0xFF, 0x00), + Color.FromRgb (0xC5, 0xFF, 0x00), + Color.FromRgb (0xBF, 0xFF, 0x00), + Color.FromRgb (0xB8, 0xFF, 0x00), + Color.FromRgb (0xB2, 0xFF, 0x00), + Color.FromRgb (0xAC, 0xFF, 0x00), + Color.FromRgb (0xA5, 0xFF, 0x00), + Color.FromRgb (0x9F, 0xFF, 0x00), + Color.FromRgb (0x99, 0xFF, 0x00), + Color.FromRgb (0x92, 0xFF, 0x00), + Color.FromRgb (0x8C, 0xFF, 0x00), + Color.FromRgb (0x85, 0xFF, 0x00), + Color.FromRgb (0x7F, 0xFF, 0x00), + Color.FromRgb (0x79, 0xFF, 0x00), + Color.FromRgb (0x72, 0xFF, 0x00), + Color.FromRgb (0x6C, 0xFF, 0x00), + Color.FromRgb (0x66, 0xFF, 0x00), + Color.FromRgb (0x5F, 0xFF, 0x00), + Color.FromRgb (0x59, 0xFF, 0x00), + Color.FromRgb (0x52, 0xFF, 0x00), + Color.FromRgb (0x4C, 0xFF, 0x00), + Color.FromRgb (0x46, 0xFF, 0x00), + Color.FromRgb (0x3F, 0xFF, 0x00), + Color.FromRgb (0x39, 0xFF, 0x00), + Color.FromRgb (0x33, 0xFF, 0x00), + Color.FromRgb (0x2C, 0xFF, 0x00), + Color.FromRgb (0x26, 0xFF, 0x00), + Color.FromRgb (0x1F, 0xFF, 0x00), + Color.FromRgb (0x19, 0xFF, 0x00), + Color.FromRgb (0x13, 0xFF, 0x00), + Color.FromRgb (0x0C, 0xFF, 0x00), + Color.FromRgb (0x0C, 0xFF, 0x00), + Color.FromRgb (0x00, 0xFF, 0x00), + Color.FromRgb (0x00, 0xFF, 0x06), + Color.FromRgb (0x00, 0xFF, 0x0C), + Color.FromRgb (0x00, 0xFF, 0x13), + Color.FromRgb (0x00, 0xFF, 0x19), + Color.FromRgb (0x00, 0xFF, 0x1F), + Color.FromRgb (0x00, 0xFF, 0x26), + Color.FromRgb (0x00, 0xFF, 0x2C), + Color.FromRgb (0x00, 0xFF, 0x33), + Color.FromRgb (0x00, 0xFF, 0x39), + Color.FromRgb (0x00, 0xFF, 0x3F), + Color.FromRgb (0x00, 0xFF, 0x46), + Color.FromRgb (0x00, 0xFF, 0x4C), + Color.FromRgb (0x00, 0xFF, 0x52), + Color.FromRgb (0x00, 0xFF, 0x59), + Color.FromRgb (0x00, 0xFF, 0x5F), + Color.FromRgb (0x00, 0xFF, 0x66), + Color.FromRgb (0x00, 0xFF, 0x6C), + Color.FromRgb (0x00, 0xFF, 0x72), + Color.FromRgb (0x00, 0xFF, 0x79), + Color.FromRgb (0x00, 0xFF, 0x7F), + Color.FromRgb (0x00, 0xFF, 0x85), + Color.FromRgb (0x00, 0xFF, 0x8C), + Color.FromRgb (0x00, 0xFF, 0x92), + Color.FromRgb (0x00, 0xFF, 0x99), + Color.FromRgb (0x00, 0xFF, 0x9F), + Color.FromRgb (0x00, 0xFF, 0xA5), + Color.FromRgb (0x00, 0xFF, 0xAC), + Color.FromRgb (0x00, 0xFF, 0xB2), + Color.FromRgb (0x00, 0xFF, 0xB8), + Color.FromRgb (0x00, 0xFF, 0xBF), + Color.FromRgb (0x00, 0xFF, 0xC5), + Color.FromRgb (0x00, 0xFF, 0xCC), + Color.FromRgb (0x00, 0xFF, 0xD2), + Color.FromRgb (0x00, 0xFF, 0xD8), + Color.FromRgb (0x00, 0xFF, 0xDF), + Color.FromRgb (0x00, 0xFF, 0xE5), + Color.FromRgb (0x00, 0xFF, 0xEB), + Color.FromRgb (0x00, 0xFF, 0xF2), + Color.FromRgb (0x00, 0xFF, 0xF8), + Color.FromRgb (0x00, 0xFF, 0xFF), + Color.FromRgb (0x00, 0xF8, 0xFF), + Color.FromRgb (0x00, 0xF2, 0xFF), + Color.FromRgb (0x00, 0xEB, 0xFF), + Color.FromRgb (0x00, 0xE5, 0xFF), + Color.FromRgb (0x00, 0xDF, 0xFF), + Color.FromRgb (0x00, 0xD8, 0xFF), + Color.FromRgb (0x00, 0xD2, 0xFF), + Color.FromRgb (0x00, 0xCC, 0xFF), + Color.FromRgb (0x00, 0xC5, 0xFF), + Color.FromRgb (0x00, 0xBF, 0xFF), + Color.FromRgb (0x00, 0xB8, 0xFF), + Color.FromRgb (0x00, 0xB2, 0xFF), + Color.FromRgb (0x00, 0xAC, 0xFF), + Color.FromRgb (0x00, 0xA5, 0xFF), + Color.FromRgb (0x00, 0x9F, 0xFF), + Color.FromRgb (0x00, 0x99, 0xFF), + Color.FromRgb (0x00, 0x92, 0xFF), + Color.FromRgb (0x00, 0x8C, 0xFF), + Color.FromRgb (0x00, 0x85, 0xFF), + Color.FromRgb (0x00, 0x7F, 0xFF), + Color.FromRgb (0x00, 0x79, 0xFF), + Color.FromRgb (0x00, 0x72, 0xFF), + Color.FromRgb (0xF0, 0xF0, 0xF0), + Color.FromRgb (0xE0, 0xE0, 0xE0), + Color.FromRgb (0xD0, 0xD0, 0xD0), + Color.FromRgb (0xC0, 0xC0, 0xC0), + Color.FromRgb (0xB0, 0xB0, 0xB0), + Color.FromRgb (0xA0, 0xA0, 0xA0), + Color.FromRgb (0x90, 0x90, 0x90), + Color.FromRgb (0x80, 0x80, 0x80), + Color.FromRgb (0x70, 0x70, 0x70), + Color.FromRgb (0x60, 0x60, 0x60), + Color.FromRgb (0x50, 0x50, 0x50), + Color.FromRgb (0x40, 0x40, 0x40), + Color.FromRgb (0x30, 0x30, 0x30), + Color.FromRgb (0x20, 0x20, 0x20), + Color.FromRgb (0x10, 0x10, 0x10), + Color.FromRgb (0x00, 0x00, 0x00), + }); + + public static readonly BitmapPalette Grayscale = new BitmapPalette (new Color[] { + Color.FromRgb (0xFF, 0xFF, 0xFF), + Color.FromRgb (0xFE, 0xFE, 0xFE), + Color.FromRgb (0xFD, 0xFD, 0xFD), + Color.FromRgb (0xFC, 0xFC, 0xFC), + Color.FromRgb (0xFB, 0xFB, 0xFB), + Color.FromRgb (0xFA, 0xFA, 0xFA), + Color.FromRgb (0xF9, 0xF9, 0xF9), + Color.FromRgb (0xF8, 0xF8, 0xF8), + Color.FromRgb (0xF7, 0xF7, 0xF7), + Color.FromRgb (0xF6, 0xF6, 0xF6), + Color.FromRgb (0xF5, 0xF5, 0xF5), + Color.FromRgb (0xF4, 0xF4, 0xF4), + Color.FromRgb (0xF3, 0xF3, 0xF3), + Color.FromRgb (0xF2, 0xF2, 0xF2), + Color.FromRgb (0xF1, 0xF1, 0xF1), + Color.FromRgb (0xF0, 0xF0, 0xF0), + Color.FromRgb (0xEF, 0xEF, 0xEF), + Color.FromRgb (0xEE, 0xEE, 0xEE), + Color.FromRgb (0xED, 0xED, 0xED), + Color.FromRgb (0xEC, 0xEC, 0xEC), + Color.FromRgb (0xEB, 0xEB, 0xEB), + Color.FromRgb (0xEA, 0xEA, 0xEA), + Color.FromRgb (0xE9, 0xE9, 0xE9), + Color.FromRgb (0xE8, 0xE8, 0xE8), + Color.FromRgb (0xE7, 0xE7, 0xE7), + Color.FromRgb (0xE6, 0xE6, 0xE6), + Color.FromRgb (0xE5, 0xE5, 0xE5), + Color.FromRgb (0xE4, 0xE4, 0xE4), + Color.FromRgb (0xE3, 0xE3, 0xE3), + Color.FromRgb (0xE2, 0xE2, 0xE2), + Color.FromRgb (0xE1, 0xE1, 0xE1), + Color.FromRgb (0xE0, 0xE0, 0xE0), + Color.FromRgb (0xDF, 0xDF, 0xDF), + Color.FromRgb (0xDE, 0xDE, 0xDE), + Color.FromRgb (0xDD, 0xDD, 0xDD), + Color.FromRgb (0xDC, 0xDC, 0xDC), + Color.FromRgb (0xDB, 0xDB, 0xDB), + Color.FromRgb (0xDA, 0xDA, 0xDA), + Color.FromRgb (0xD9, 0xD9, 0xD9), + Color.FromRgb (0xD8, 0xD8, 0xD8), + Color.FromRgb (0xD7, 0xD7, 0xD7), + Color.FromRgb (0xD6, 0xD6, 0xD6), + Color.FromRgb (0xD5, 0xD5, 0xD5), + Color.FromRgb (0xD4, 0xD4, 0xD4), + Color.FromRgb (0xD3, 0xD3, 0xD3), + Color.FromRgb (0xD2, 0xD2, 0xD2), + Color.FromRgb (0xD1, 0xD1, 0xD1), + Color.FromRgb (0xD0, 0xD0, 0xD0), + Color.FromRgb (0xCF, 0xCF, 0xCF), + Color.FromRgb (0xCE, 0xCE, 0xCE), + Color.FromRgb (0xCD, 0xCD, 0xCD), + Color.FromRgb (0xCC, 0xCC, 0xCC), + Color.FromRgb (0xCB, 0xCB, 0xCB), + Color.FromRgb (0xCA, 0xCA, 0xCA), + Color.FromRgb (0xC9, 0xC9, 0xC9), + Color.FromRgb (0xC8, 0xC8, 0xC8), + Color.FromRgb (0xC7, 0xC7, 0xC7), + Color.FromRgb (0xC6, 0xC6, 0xC6), + Color.FromRgb (0xC5, 0xC5, 0xC5), + Color.FromRgb (0xC4, 0xC4, 0xC4), + Color.FromRgb (0xC3, 0xC3, 0xC3), + Color.FromRgb (0xC2, 0xC2, 0xC2), + Color.FromRgb (0xC1, 0xC1, 0xC1), + Color.FromRgb (0xC0, 0xC0, 0xC0), + Color.FromRgb (0xBF, 0xBF, 0xBF), + Color.FromRgb (0xBE, 0xBE, 0xBE), + Color.FromRgb (0xBD, 0xBD, 0xBD), + Color.FromRgb (0xBC, 0xBC, 0xBC), + Color.FromRgb (0xBB, 0xBB, 0xBB), + Color.FromRgb (0xBA, 0xBA, 0xBA), + Color.FromRgb (0xB9, 0xB9, 0xB9), + Color.FromRgb (0xB8, 0xB8, 0xB8), + Color.FromRgb (0xB7, 0xB7, 0xB7), + Color.FromRgb (0xB6, 0xB6, 0xB6), + Color.FromRgb (0xB5, 0xB5, 0xB5), + Color.FromRgb (0xB4, 0xB4, 0xB4), + Color.FromRgb (0xB3, 0xB3, 0xB3), + Color.FromRgb (0xB2, 0xB2, 0xB2), + Color.FromRgb (0xB1, 0xB1, 0xB1), + Color.FromRgb (0xB0, 0xB0, 0xB0), + Color.FromRgb (0xAF, 0xAF, 0xAF), + Color.FromRgb (0xAE, 0xAE, 0xAE), + Color.FromRgb (0xAD, 0xAD, 0xAD), + Color.FromRgb (0xAC, 0xAC, 0xAC), + Color.FromRgb (0xAB, 0xAB, 0xAB), + Color.FromRgb (0xAA, 0xAA, 0xAA), + Color.FromRgb (0xA9, 0xA9, 0xA9), + Color.FromRgb (0xA8, 0xA8, 0xA8), + Color.FromRgb (0xA7, 0xA7, 0xA7), + Color.FromRgb (0xA6, 0xA6, 0xA6), + Color.FromRgb (0xA5, 0xA5, 0xA5), + Color.FromRgb (0xA4, 0xA4, 0xA4), + Color.FromRgb (0xA3, 0xA3, 0xA3), + Color.FromRgb (0xA2, 0xA2, 0xA2), + Color.FromRgb (0xA1, 0xA1, 0xA1), + Color.FromRgb (0xA0, 0xA0, 0xA0), + Color.FromRgb (0x9F, 0x9F, 0x9F), + Color.FromRgb (0x9E, 0x9E, 0x9E), + Color.FromRgb (0x9D, 0x9D, 0x9D), + Color.FromRgb (0x9C, 0x9C, 0x9C), + Color.FromRgb (0x9B, 0x9B, 0x9B), + Color.FromRgb (0x9A, 0x9A, 0x9A), + Color.FromRgb (0x99, 0x99, 0x99), + Color.FromRgb (0x98, 0x98, 0x98), + Color.FromRgb (0x97, 0x97, 0x97), + Color.FromRgb (0x96, 0x96, 0x96), + Color.FromRgb (0x95, 0x95, 0x95), + Color.FromRgb (0x94, 0x94, 0x94), + Color.FromRgb (0x93, 0x93, 0x93), + Color.FromRgb (0x92, 0x92, 0x92), + Color.FromRgb (0x91, 0x91, 0x91), + Color.FromRgb (0x90, 0x90, 0x90), + Color.FromRgb (0x8F, 0x8F, 0x8F), + Color.FromRgb (0x8E, 0x8E, 0x8E), + Color.FromRgb (0x8D, 0x8D, 0x8D), + Color.FromRgb (0x8C, 0x8C, 0x8C), + Color.FromRgb (0x8B, 0x8B, 0x8B), + Color.FromRgb (0x8A, 0x8A, 0x8A), + Color.FromRgb (0x89, 0x89, 0x89), + Color.FromRgb (0x88, 0x88, 0x88), + Color.FromRgb (0x87, 0x87, 0x87), + Color.FromRgb (0x86, 0x86, 0x86), + Color.FromRgb (0x85, 0x85, 0x85), + Color.FromRgb (0x84, 0x84, 0x84), + Color.FromRgb (0x83, 0x83, 0x83), + Color.FromRgb (0x82, 0x82, 0x82), + Color.FromRgb (0x81, 0x81, 0x81), + Color.FromRgb (0x80, 0x80, 0x80), + Color.FromRgb (0x7F, 0x7F, 0x7F), + Color.FromRgb (0x7E, 0x7E, 0x7E), + Color.FromRgb (0x7D, 0x7D, 0x7D), + Color.FromRgb (0x7C, 0x7C, 0x7C), + Color.FromRgb (0x7B, 0x7B, 0x7B), + Color.FromRgb (0x7A, 0x7A, 0x7A), + Color.FromRgb (0x79, 0x79, 0x79), + Color.FromRgb (0x78, 0x78, 0x78), + Color.FromRgb (0x77, 0x77, 0x77), + Color.FromRgb (0x76, 0x76, 0x76), + Color.FromRgb (0x75, 0x75, 0x75), + Color.FromRgb (0x74, 0x74, 0x74), + Color.FromRgb (0x73, 0x73, 0x73), + Color.FromRgb (0x72, 0x72, 0x72), + Color.FromRgb (0x71, 0x71, 0x71), + Color.FromRgb (0x70, 0x70, 0x70), + Color.FromRgb (0x6F, 0x6F, 0x6F), + Color.FromRgb (0x6E, 0x6E, 0x6E), + Color.FromRgb (0x6D, 0x6D, 0x6D), + Color.FromRgb (0x6C, 0x6C, 0x6C), + Color.FromRgb (0x6B, 0x6B, 0x6B), + Color.FromRgb (0x6A, 0x6A, 0x6A), + Color.FromRgb (0x69, 0x69, 0x69), + Color.FromRgb (0x68, 0x68, 0x68), + Color.FromRgb (0x67, 0x67, 0x67), + Color.FromRgb (0x66, 0x66, 0x66), + Color.FromRgb (0x65, 0x65, 0x65), + Color.FromRgb (0x64, 0x64, 0x64), + Color.FromRgb (0x63, 0x63, 0x63), + Color.FromRgb (0x62, 0x62, 0x62), + Color.FromRgb (0x61, 0x61, 0x61), + Color.FromRgb (0x60, 0x60, 0x60), + Color.FromRgb (0x5F, 0x5F, 0x5F), + Color.FromRgb (0x5E, 0x5E, 0x5E), + Color.FromRgb (0x5D, 0x5D, 0x5D), + Color.FromRgb (0x5C, 0x5C, 0x5C), + Color.FromRgb (0x5B, 0x5B, 0x5B), + Color.FromRgb (0x5A, 0x5A, 0x5A), + Color.FromRgb (0x59, 0x59, 0x59), + Color.FromRgb (0x58, 0x58, 0x58), + Color.FromRgb (0x57, 0x57, 0x57), + Color.FromRgb (0x56, 0x56, 0x56), + Color.FromRgb (0x55, 0x55, 0x55), + Color.FromRgb (0x54, 0x54, 0x54), + Color.FromRgb (0x53, 0x53, 0x53), + Color.FromRgb (0x52, 0x52, 0x52), + Color.FromRgb (0x51, 0x51, 0x51), + Color.FromRgb (0x50, 0x50, 0x50), + Color.FromRgb (0x4F, 0x4F, 0x4F), + Color.FromRgb (0x4E, 0x4E, 0x4E), + Color.FromRgb (0x4D, 0x4D, 0x4D), + Color.FromRgb (0x4C, 0x4C, 0x4C), + Color.FromRgb (0x4B, 0x4B, 0x4B), + Color.FromRgb (0x4A, 0x4A, 0x4A), + Color.FromRgb (0x49, 0x49, 0x49), + Color.FromRgb (0x48, 0x48, 0x48), + Color.FromRgb (0x47, 0x47, 0x47), + Color.FromRgb (0x46, 0x46, 0x46), + Color.FromRgb (0x45, 0x45, 0x45), + Color.FromRgb (0x44, 0x44, 0x44), + Color.FromRgb (0x43, 0x43, 0x43), + Color.FromRgb (0x42, 0x42, 0x42), + Color.FromRgb (0x41, 0x41, 0x41), + Color.FromRgb (0x40, 0x40, 0x40), + Color.FromRgb (0x3F, 0x3F, 0x3F), + Color.FromRgb (0x3E, 0x3E, 0x3E), + Color.FromRgb (0x3D, 0x3D, 0x3D), + Color.FromRgb (0x3C, 0x3C, 0x3C), + Color.FromRgb (0x3B, 0x3B, 0x3B), + Color.FromRgb (0x3A, 0x3A, 0x3A), + Color.FromRgb (0x39, 0x39, 0x39), + Color.FromRgb (0x38, 0x38, 0x38), + Color.FromRgb (0x37, 0x37, 0x37), + Color.FromRgb (0x36, 0x36, 0x36), + Color.FromRgb (0x35, 0x35, 0x35), + Color.FromRgb (0x34, 0x34, 0x34), + Color.FromRgb (0x33, 0x33, 0x33), + Color.FromRgb (0x32, 0x32, 0x32), + Color.FromRgb (0x31, 0x31, 0x31), + Color.FromRgb (0x30, 0x30, 0x30), + Color.FromRgb (0x2F, 0x2F, 0x2F), + Color.FromRgb (0x2E, 0x2E, 0x2E), + Color.FromRgb (0x2D, 0x2D, 0x2D), + Color.FromRgb (0x2C, 0x2C, 0x2C), + Color.FromRgb (0x2B, 0x2B, 0x2B), + Color.FromRgb (0x2A, 0x2A, 0x2A), + Color.FromRgb (0x29, 0x29, 0x29), + Color.FromRgb (0x28, 0x28, 0x28), + Color.FromRgb (0x27, 0x27, 0x27), + Color.FromRgb (0x26, 0x26, 0x26), + Color.FromRgb (0x25, 0x25, 0x25), + Color.FromRgb (0x24, 0x24, 0x24), + Color.FromRgb (0x23, 0x23, 0x23), + Color.FromRgb (0x22, 0x22, 0x22), + Color.FromRgb (0x21, 0x21, 0x21), + Color.FromRgb (0x20, 0x20, 0x20), + Color.FromRgb (0x1F, 0x1F, 0x1F), + Color.FromRgb (0x1E, 0x1E, 0x1E), + Color.FromRgb (0x1D, 0x1D, 0x1D), + Color.FromRgb (0x1C, 0x1C, 0x1C), + Color.FromRgb (0x1B, 0x1B, 0x1B), + Color.FromRgb (0x1A, 0x1A, 0x1A), + Color.FromRgb (0x19, 0x19, 0x19), + Color.FromRgb (0x18, 0x18, 0x18), + Color.FromRgb (0x17, 0x17, 0x17), + Color.FromRgb (0x16, 0x16, 0x16), + Color.FromRgb (0x15, 0x15, 0x15), + Color.FromRgb (0x14, 0x14, 0x14), + Color.FromRgb (0x13, 0x13, 0x13), + Color.FromRgb (0x12, 0x12, 0x12), + Color.FromRgb (0x11, 0x11, 0x11), + Color.FromRgb (0x10, 0x10, 0x10), + Color.FromRgb (0x0F, 0x0F, 0x0F), + Color.FromRgb (0x0E, 0x0E, 0x0E), + Color.FromRgb (0x0D, 0x0D, 0x0D), + Color.FromRgb (0x0C, 0x0C, 0x0C), + Color.FromRgb (0x0B, 0x0B, 0x0B), + Color.FromRgb (0x0A, 0x0A, 0x0A), + Color.FromRgb (0x09, 0x09, 0x09), + Color.FromRgb (0x08, 0x08, 0x08), + Color.FromRgb (0x07, 0x07, 0x07), + Color.FromRgb (0x06, 0x06, 0x06), + Color.FromRgb (0x05, 0x05, 0x05), + Color.FromRgb (0x04, 0x04, 0x04), + Color.FromRgb (0x03, 0x03, 0x03), + Color.FromRgb (0x02, 0x02, 0x02), + Color.FromRgb (0x01, 0x01, 0x01), + Color.FromRgb (0x00, 0x00, 0x00), + }); + } +} diff --git a/ArcFormats/Maika/ArcMK2.cs b/ArcFormats/Maika/ArcMK2.cs index 7214a5e5..3c1741a4 100644 --- a/ArcFormats/Maika/ArcMK2.cs +++ b/ArcFormats/Maika/ArcMK2.cs @@ -142,7 +142,7 @@ namespace GameRes.Formats.Maika Stream input; // XXX scrambling might be applicable for 'E1' signatures only - if (scheme.ScrambledSize > 0) + if (0x3145 == signature && scheme.ScrambledSize > 0) { var prefix = arc.File.View.ReadBytes (entry.Offset+10, scheme.ScrambledSize); foreach (var pair in scheme.ScrambleMap) diff --git a/ArcFormats/Marble/ImagePRS.cs b/ArcFormats/Marble/ImagePRS.cs index fe76bf8a..a3a25051 100644 --- a/ArcFormats/Marble/ImagePRS.cs +++ b/ArcFormats/Marble/ImagePRS.cs @@ -176,6 +176,7 @@ namespace GameRes.Formats.Marble if (3 == b) { length += 9; +// length = Math.Min(m_output.Length - dst, length); int read = m_input.Read (m_output, dst, length); if (read < length) break; diff --git a/ArcFormats/MultiFileArchive.cs b/ArcFormats/MultiFileArchive.cs index 8d415ddd..a850faf3 100644 --- a/ArcFormats/MultiFileArchive.cs +++ b/ArcFormats/MultiFileArchive.cs @@ -75,9 +75,7 @@ namespace GameRes.Formats } part_offset = part_end_offset; } - if (null == input) - return Stream.Null; - return input; + return input ?? Stream.Null; } catch { diff --git a/ArcFormats/MyAdv/ArcPAC.cs b/ArcFormats/MyAdv/ArcPAC.cs new file mode 100644 index 00000000..c98083af --- /dev/null +++ b/ArcFormats/MyAdv/ArcPAC.cs @@ -0,0 +1,103 @@ +//! \file ArcPAC.cs +//! \date 2022 Jun 01 +//! \brief MyAdv engine resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using GameRes.Compression; +using ICSharpCode.SharpZipLib.Zip.Compression; + +namespace GameRes.Formats.MyAdv +{ + [Export(typeof(ArchiveFormat))] + public class PacOpener : ArchiveFormat + { + public override string Tag { get { return "PAC/MyAdv"; } } + public override string Description { get { return "MyAdv engine resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + public PacOpener () + { + ContainedFormats = new[] { "DDS", "OGG", "TXT" }; + } + + public override ArcFile TryOpen (ArcView file) + { + int count = file.View.ReadInt32 (0); + if (!IsSaneCount (count)) + return null; + + var name_buffer = new byte[0x100]; + var zlib_buffer = new byte[0x100]; + long pos = 4; + var zlib = new Inflater(); + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + int name_len = file.View.ReadInt32 (pos); + if (name_len <= 0 || name_len > name_buffer.Length) + return null; + int unpacked_size = file.View.ReadInt32 (pos+4); + if (unpacked_size < name_len || unpacked_size > name_buffer.Length) + return null; + int packed_size = file.View.ReadInt32 (pos+8); + if (packed_size <= 0 || packed_size > zlib_buffer.Length) + return null; + pos += 12; + file.View.Read (pos, zlib_buffer, 0, (uint)packed_size); + pos += packed_size; + zlib.Reset(); + zlib.SetInput (zlib_buffer, 0, packed_size); + zlib.Inflate (name_buffer); + var name = Encodings.cp932.GetString (name_buffer, 0, name_len); + var entry = Create (name); + dir.Add (entry); + } + foreach (PackedEntry entry in dir) + { + entry.Offset = file.View.ReadUInt32 (pos); + entry.Size = file.View.ReadUInt32 (pos+4); + entry.UnpackedSize = file.View.ReadUInt32 (pos+8); + entry.IsPacked = true; + pos += 12; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pent = entry as PackedEntry; + var input = arc.File.CreateStream (entry.Offset, entry.Size); + if (null == pent || !pent.IsPacked) + return input; + return new ZLibStream (input, CompressionMode.Decompress); + } + } +} diff --git a/ArcFormats/NScripter/Script.cs b/ArcFormats/NScripter/Script.cs new file mode 100644 index 00000000..43b05ba9 --- /dev/null +++ b/ArcFormats/NScripter/Script.cs @@ -0,0 +1,53 @@ +//! \file Script.cs +//! \date 2023 Aug 23 +//! \brief +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.NScripter +{ + [Export(typeof(ScriptFormat))] + public class NSOpener : GenericScriptFormat + { + public override string Tag { get => "NScripter"; } + public override string Description { get => "NScripter engine script file"; } + public override uint Signature { get => 0; } + + public override bool IsScript (IBinaryStream file) + { + return VFS.IsPathEqualsToFileName (file.Name, "nscript.dat"); + } + + public override Stream ConvertFrom (IBinaryStream file) + { + return new XoredStream (file.AsStream, 0x84); + } + + public override Stream ConvertBack (IBinaryStream file) + { + return new XoredStream (file.AsStream, 0x84); + } + } +} diff --git a/ArcFormats/ArcNEKO.cs b/ArcFormats/Nekopack/ArcNEKO.cs similarity index 59% rename from ArcFormats/ArcNEKO.cs rename to ArcFormats/Nekopack/ArcNEKO.cs index 5f55e02f..96f2dea9 100644 --- a/ArcFormats/ArcNEKO.cs +++ b/ArcFormats/Nekopack/ArcNEKO.cs @@ -377,256 +377,4 @@ namespace GameRes.Formats.Neko 0x58, 0xC5, 0x74, 0xB7, 0x8E, 0x7D, 0x89, 0x8A, 0x56, 0x4D, 0x86, 0x94, 0x9A, 0x4C, 0x92, 0xB0, }; } - - [Export(typeof(ArchiveFormat))] - public class Pak2Opener : ArchiveFormat - { - public override string Tag { get { return "NEKOPACK/2"; } } - public override string Description { get { return "NekoPack resource archive"; } } - public override uint Signature { get { return 0x4F4B454E; } } // "NEKO" - public override bool IsHierarchic { get { return true; } } - public override bool CanWrite { get { return false; } } - - public Pak2Opener () - { - Extensions = new string[] { "dat" }; - } - - public override ArcFile TryOpen (ArcView file) - { - if (!file.View.AsciiEqual (4, "PACK")) - return null; - - uint init_key = file.View.ReadUInt32 (0xC); - var xdec = new NekoXCode (init_key); - uint seed = file.View.ReadUInt32 (0x10); - var buffer = file.View.ReadBytes (0x14, 8); - xdec.Decrypt (seed, buffer, 0, 8); - - uint index_size = LittleEndian.ToUInt32 (buffer, 0); - if (index_size < 0x14 || index_size != LittleEndian.ToUInt32 (buffer, 4)) - return null; - var index = new byte[(index_size + 7u) & ~7u]; - if (file.View.Read (0x1C, index, 0, index_size) < index_size) - return null; - xdec.Decrypt (seed, index, 0, index.Length); - - using (var reader = new IndexReader (file, xdec, index, (int)index_size)) - { - var dir = reader.Parse (0x1C+index.Length); - if (null == dir) - return null; - reader.DetectTypes (dir, entry => { - uint key = file.View.ReadUInt32 (entry.Offset); - file.View.Read (entry.Offset+12, buffer, 0, 8); - xdec.Decrypt (key, buffer, 0, 8); - return LittleEndian.ToUInt32 (buffer, 0); - }); - return new NekoArchive (file, this, dir, xdec); - } - } - - public override Stream OpenEntry (ArcFile arc, Entry entry) - { - var narc = arc as NekoArchive; - if (null == narc || entry.Size <= 12) - return base.OpenEntry (arc, entry); - uint key = arc.File.View.ReadUInt32 (entry.Offset); - var data = new byte[entry.Size]; - arc.File.View.Read (entry.Offset+4, data, 0, 8); - narc.Decoder.Decrypt (key, data, 0, 8); - int size = LittleEndian.ToInt32 (data, 0); - if (size != LittleEndian.ToInt32 (data, 4)) - { - Trace.WriteLine ("entry decryption failed", "[NEKOPACK]"); - return base.OpenEntry (arc, entry); - } - int aligned_size = (size + 7) & ~7; - if (aligned_size > data.Length) - data = new byte[aligned_size]; - arc.File.View.Read (entry.Offset+12, data, 0, (uint)size); - narc.Decoder.Decrypt (key, data, 0, aligned_size); - return new BinMemoryStream (data, 0, size, entry.Name); - } - } - - internal class NekoXCode : INekoFormat - { - uint m_seed; - uint[] m_random; - SimdProgram m_program; - - public NekoXCode (uint init_key) - { - m_seed = init_key; - m_random = InitTable (init_key); - m_program = new SimdProgram (init_key); - } - - public void Decrypt (uint key, byte[] input, int offset, int length) - { - for (int i = 1; i < 7; ++i) - { - uint src = key % 0x28 * 2; - m_program.mm[i] = m_random[src] | (ulong)m_random[src+1] << 32; - key /= 0x28; - } - m_program.Execute (input, offset, length); - } - - public uint HashFromName (byte[] str, int offset, int length) - { - uint hash = m_seed; - for (int i = 0; i < length; ++i) - { - hash = 0x100002A * (ShiftMap[str[offset+i] & 0xFF] ^ hash); - } - return hash; - } - - public DirRecord ReadDir (IBinaryStream input) - { - uint hash = input.ReadUInt32(); - int count = input.ReadInt32(); - if (count != input.ReadInt32()) - throw new InvalidFormatException(); - return new DirRecord { Hash = hash, FileCount = count }; - } - - public long NextOffset (Entry entry) - { - return entry.Offset + entry.Size; - } - - static readonly byte[] ShiftMap = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc9, 0xca, 0x00, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0x00, 0xd2, 0xd3, 0x27, 0x25, 0xc8, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0x00, - 0xd6, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0xd7, 0xc8, 0xd8, 0xd9, 0x26, - 0xda, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0xdb, 0x00, 0xdc, 0xdd, 0x00, - 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, - 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, - }; - - class SimdProgram - { - public ulong[] mm = new ulong[7]; - - Action[] m_transform = new Action[4]; - Action[] m_shuffle = new Action[6]; - - Action[] TransformList; - Action[] ShuffleList; - - public SimdProgram (uint key) - { - TransformList = new Action[] { - pxor, paddb, paddw, paddd, psubb, psubw, psubd, - pxor, psubb, psubw, psubd, paddb, paddw, paddd, - }; - ShuffleList = new Action[] { - paddq_1_2, paddq_2_3, paddq_3_4, paddq_4_5, paddq_5_6, paddq_6_1, - }; - - GenerateProgram (key); - } - - void pxor (int i) { mm[0] ^= mm[i]; } - void paddb (int i) { mm[0] = MMX.PAddB (mm[0], mm[i]); } - void paddw (int i) { mm[0] = MMX.PAddW (mm[0], mm[i]); } - void paddd (int i) { mm[0] = MMX.PAddD (mm[0], mm[i]); } - void psubb (int i) { mm[0] = MMX.PSubB (mm[0], mm[i]); } - void psubw (int i) { mm[0] = MMX.PSubW (mm[0], mm[i]); } - void psubd (int i) { mm[0] = MMX.PSubD (mm[0], mm[i]); } - - void paddq_1_2 () { mm[1] += mm[2]; } - void paddq_2_3 () { mm[2] += mm[3]; } - void paddq_3_4 () { mm[3] += mm[4]; } - void paddq_4_5 () { mm[4] += mm[5]; } - void paddq_5_6 () { mm[5] += mm[6]; } - void paddq_6_1 () { mm[6] += mm[1]; } - - void GenerateProgram (uint key) - { - int t1 = 7 + (int)(key >> 28); - int cmd_base = (int)key & 0xffff; - int arg_base = (int)(key >> 16) & 0xfff; - for (int i = 3; i >= 0; --i) - { - int cmd = ((cmd_base >> (4 * i)) + t1) % TransformList.Length; - int arg = (arg_base >> (3 * i)) % 6 + 1; - m_transform[3-i] = () => TransformList[cmd] (arg); - } - for (uint i = 0; i < 6; ++i) - { - m_shuffle[i] = ShuffleList[(i + key) % (uint)ShuffleList.Length]; - } - } - - public unsafe void Execute (byte[] input, int offset, int length) - { - if (offset < 0 || offset > input.Length) - throw new ArgumentException ("offset"); - int count = Math.Min (length, input.Length-offset) / 8; - if (0 == count) - return; - fixed (byte* data = &input[offset]) - { - ulong* data64 = (ulong*)data; - for (;;) - { - mm[0] = *data64; - foreach (var cmd in m_transform) - cmd(); - *data64++ = mm[0]; - if (1 == count--) - break; - foreach (var cmd in m_shuffle) - cmd(); - } - } - } - } - - static uint[] InitTable (uint key) - { - uint a = 0; - uint b = 0; - do - { - a <<= 1; - b ^= 1; - a = ((a | b) << (int)(key & 1)) | b; - key >>= 1; - } - while (0 == (a & 0x80000000)); - key = a << 1; - a = key + Binary.BigEndian (key); - byte count = (byte)key; - do - { - b = key ^ a; - a = (b << 4) ^ (b >> 4) ^ (b << 3) ^ (b >> 3) ^ b; - } - while (--count != 0); - - var table = new uint[154]; - for (int i = 0; i < table.Length; ++i) - { - b = key ^ a; - a = (b << 4) ^ (b >> 4) ^ (b << 3) ^ (b >> 3) ^ b; - table[i] = a; - } - return table; - } - } } diff --git a/ArcFormats/Nekopack/ArcNEKO2.cs b/ArcFormats/Nekopack/ArcNEKO2.cs new file mode 100644 index 00000000..309cec82 --- /dev/null +++ b/ArcFormats/Nekopack/ArcNEKO2.cs @@ -0,0 +1,285 @@ +//! \file ArcNEKO2.cs +//! \date 2022 Jun 17 +//! \brief Nekopack archive format implementation. +// +// Copyright (C) 2015-2016 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; + +namespace GameRes.Formats.Neko +{ + [Export(typeof(ArchiveFormat))] + public class Pak2Opener : ArchiveFormat + { + public override string Tag { get { return "NEKOPACK/2"; } } + public override string Description { get { return "NekoPack resource archive"; } } + public override uint Signature { get { return 0x4F4B454E; } } // "NEKO" + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + public Pak2Opener () + { + Extensions = new string[] { "dat" }; + } + + public override ArcFile TryOpen (ArcView file) + { + if (!file.View.AsciiEqual (4, "PACK")) + return null; + + uint init_key = file.View.ReadUInt32 (0xC); + var xdec = new NekoXCode (init_key); + uint seed = file.View.ReadUInt32 (0x10); + var buffer = file.View.ReadBytes (0x14, 8); + xdec.Decrypt (seed, buffer, 0, 8); + + uint index_size = LittleEndian.ToUInt32 (buffer, 0); + if (index_size < 0x14 || index_size != LittleEndian.ToUInt32 (buffer, 4)) + return null; + var index = new byte[(index_size + 7u) & ~7u]; + if (file.View.Read (0x1C, index, 0, index_size) < index_size) + return null; + xdec.Decrypt (seed, index, 0, index.Length); + + using (var reader = new IndexReader (file, xdec, index, (int)index_size)) + { + var dir = reader.Parse (0x1C+index.Length); + if (null == dir) + return null; + reader.DetectTypes (dir, entry => { + uint key = file.View.ReadUInt32 (entry.Offset); + file.View.Read (entry.Offset+12, buffer, 0, 8); + xdec.Decrypt (key, buffer, 0, 8); + return LittleEndian.ToUInt32 (buffer, 0); + }); + return new NekoArchive (file, this, dir, xdec); + } + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var narc = arc as NekoArchive; + if (null == narc || entry.Size <= 12) + return base.OpenEntry (arc, entry); + uint key = arc.File.View.ReadUInt32 (entry.Offset); + var data = new byte[entry.Size]; + arc.File.View.Read (entry.Offset+4, data, 0, 8); + narc.Decoder.Decrypt (key, data, 0, 8); + int size = LittleEndian.ToInt32 (data, 0); + if (size != LittleEndian.ToInt32 (data, 4)) + { + Trace.WriteLine ("entry decryption failed", "[NEKOPACK]"); + return base.OpenEntry (arc, entry); + } + int aligned_size = (size + 7) & ~7; + if (aligned_size > data.Length) + data = new byte[aligned_size]; + arc.File.View.Read (entry.Offset+12, data, 0, (uint)size); + narc.Decoder.Decrypt (key, data, 0, aligned_size); + return new BinMemoryStream (data, 0, size, entry.Name); + } + } + + internal class NekoXCode : INekoFormat + { + uint m_seed; + uint[] m_random; + SimdProgram m_program; + + public NekoXCode (uint init_key) + { + m_seed = init_key; + m_random = InitTable (init_key); + m_program = new SimdProgram (init_key); + } + + public void Decrypt (uint key, byte[] input, int offset, int length) + { + for (int i = 1; i < 7; ++i) + { + uint src = key % 0x28 * 2; + m_program.mm[i] = m_random[src] | (ulong)m_random[src+1] << 32; + key /= 0x28; + } + m_program.Execute (input, offset, length); + } + + public uint HashFromName (byte[] str, int offset, int length) + { + uint hash = m_seed; + for (int i = 0; i < length; ++i) + { + hash = 0x100002A * (ShiftMap[str[offset+i] & 0xFF] ^ hash); + } + return hash; + } + + public DirRecord ReadDir (IBinaryStream input) + { + uint hash = input.ReadUInt32(); + int count = input.ReadInt32(); + if (count != input.ReadInt32()) + throw new InvalidFormatException(); + return new DirRecord { Hash = hash, FileCount = count }; + } + + public long NextOffset (Entry entry) + { + return entry.Offset + entry.Size; + } + + static readonly byte[] ShiftMap = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc9, 0xca, 0x00, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0x00, 0xd2, 0xd3, 0x27, 0x25, 0xc8, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0x00, + 0xd6, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0xd7, 0xc8, 0xd8, 0xd9, 0x26, + 0xda, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0xdb, 0x00, 0xdc, 0xdd, 0x00, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, + 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, + }; + + class SimdProgram + { + public ulong[] mm = new ulong[7]; + + Action[] m_transform = new Action[4]; + Action[] m_shuffle = new Action[6]; + + Action[] TransformList; + Action[] ShuffleList; + + public SimdProgram (uint key) + { + TransformList = new Action[] { + pxor, paddb, paddw, paddd, psubb, psubw, psubd, + pxor, psubb, psubw, psubd, paddb, paddw, paddd, + }; + ShuffleList = new Action[] { + paddq_1_2, paddq_2_3, paddq_3_4, paddq_4_5, paddq_5_6, paddq_6_1, + }; + + GenerateProgram (key); + } + + void pxor (int i) { mm[0] ^= mm[i]; } + void paddb (int i) { mm[0] = MMX.PAddB (mm[0], mm[i]); } + void paddw (int i) { mm[0] = MMX.PAddW (mm[0], mm[i]); } + void paddd (int i) { mm[0] = MMX.PAddD (mm[0], mm[i]); } + void psubb (int i) { mm[0] = MMX.PSubB (mm[0], mm[i]); } + void psubw (int i) { mm[0] = MMX.PSubW (mm[0], mm[i]); } + void psubd (int i) { mm[0] = MMX.PSubD (mm[0], mm[i]); } + + void paddq_1_2 () { mm[1] += mm[2]; } + void paddq_2_3 () { mm[2] += mm[3]; } + void paddq_3_4 () { mm[3] += mm[4]; } + void paddq_4_5 () { mm[4] += mm[5]; } + void paddq_5_6 () { mm[5] += mm[6]; } + void paddq_6_1 () { mm[6] += mm[1]; } + + void GenerateProgram (uint key) + { + int t1 = 7 + (int)(key >> 28); + int cmd_base = (int)key & 0xffff; + int arg_base = (int)(key >> 16) & 0xfff; + for (int i = 3; i >= 0; --i) + { + int cmd = ((cmd_base >> (4 * i)) + t1) % TransformList.Length; + int arg = (arg_base >> (3 * i)) % 6 + 1; + m_transform[3-i] = () => TransformList[cmd] (arg); + } + for (uint i = 0; i < 6; ++i) + { + m_shuffle[i] = ShuffleList[(i + key) % (uint)ShuffleList.Length]; + } + } + + public unsafe void Execute (byte[] input, int offset, int length) + { + if (offset < 0 || offset > input.Length) + throw new ArgumentException ("offset"); + int count = Math.Min (length, input.Length-offset) / 8; + if (0 == count) + return; + fixed (byte* data = &input[offset]) + { + ulong* data64 = (ulong*)data; + for (;;) + { + mm[0] = *data64; + foreach (var cmd in m_transform) + cmd(); + *data64++ = mm[0]; + if (1 == count--) + break; + foreach (var cmd in m_shuffle) + cmd(); + } + } + } + } + + static uint[] InitTable (uint key) + { + uint a = 0; + uint b = 0; + do + { + a <<= 1; + b ^= 1; + a = ((a | b) << (int)(key & 1)) | b; + key >>= 1; + } + while (0 == (a & 0x80000000)); + key = a << 1; + a = key + Binary.BigEndian (key); + byte count = (byte)key; + do + { + b = key ^ a; + a = (b << 4) ^ (b >> 4) ^ (b << 3) ^ (b >> 3) ^ b; + } + while (--count != 0); + + var table = new uint[154]; + for (int i = 0; i < table.Length; ++i) + { + b = key ^ a; + a = (b << 4) ^ (b >> 4) ^ (b << 3) ^ (b >> 3) ^ b; + table[i] = a; + } + return table; + } + } +} diff --git a/ArcFormats/Nekopack/ArcNEKO3.cs b/ArcFormats/Nekopack/ArcNEKO3.cs new file mode 100644 index 00000000..2693299e --- /dev/null +++ b/ArcFormats/Nekopack/ArcNEKO3.cs @@ -0,0 +1,157 @@ +//! \file ArcNEKO3.cs +//! \date 2022 Jun 17 +//! \brief Nekopack archive format implementation. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.Neko +{ + internal class Neko3Archive : ArcFile + { + public readonly byte[] Key; + + public Neko3Archive (ArcView arc, ArchiveFormat impl, ICollection dir, byte[] key) + : base (arc, impl, dir) + { + Key = key; + } + } + + internal class Neko3Entry : Entry + { + public ushort Seed; + } + + [Export(typeof(ArchiveFormat))] + public class Pak3Opener : ArchiveFormat + { + public override string Tag { get { return "NEKOPACK/3"; } } + public override string Description { get { return "NekoPack resource archive"; } } + public override uint Signature { get { return 0x4F4B454E; } } // "NEKO" + public override bool IsHierarchic { get { return true; } } + public override bool CanWrite { get { return false; } } + + public Pak3Opener () + { + Extensions = new string[] { "dat" }; + } + + public override ArcFile TryOpen (ArcView file) + { + if (!file.View.AsciiEqual (4, "PACK") || file.MaxOffset <= 0x410) + return null; + + uint seed = file.View.ReadUInt32 (0xC); + int count = (int)(seed % 7u) + 3; + var key = file.View.ReadBytes (0x10, 0x400); + while (count --> 0) + { + Decrypt (key, 0x400, key, (ushort)seed, true); + } + seed = file.View.ReadUInt16 (0x410); + var index_info = file.View.ReadBytes (0x414, 8); + Decrypt (index_info, 8, key, (ushort)seed); + uint index_size = LittleEndian.ToUInt32 (index_info, 0); + long data_offset = 0x41CL + index_size; + if (data_offset >= file.MaxOffset) + return null; + var index = file.View.ReadBytes (0x41C, index_size); + Decrypt (index, index.Length, key, (ushort)seed); + + var dir = new List(); + using (var input = new BinMemoryStream (index, file.Name)) + { + int dir_count = input.ReadInt32(); + if (!IsSaneCount (dir_count)) + return null; + for (int d = 0; d < dir_count; ++d) + { + int name_len = input.ReadUInt8(); + string dir_name = input.ReadCString (name_len); + if (string.IsNullOrEmpty (dir_name)) + return null; + int file_count = input.ReadInt32(); + if (!IsSaneCount (file_count)) + return null; + for (int i = 0; i < file_count; ++i) + { + input.ReadByte(); + name_len = input.ReadUInt8(); + string name = input.ReadCString (name_len); + name = string.Join ("/", dir_name, name); + var entry = Create (name); + entry.Offset = data_offset + input.ReadUInt32(); + dir.Add (entry); + } + } + } + var buffer = new byte[12]; + foreach (Neko3Entry entry in dir) + { + entry.Seed = file.View.ReadUInt16 (entry.Offset); + file.View.Read (entry.Offset+4, buffer, 0, 8); + Decrypt (buffer, 8, key, entry.Seed); + entry.Size = LittleEndian.ToUInt32 (buffer, 0); + entry.Offset += 12; + } + return new Neko3Archive (file, this, dir, key); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var narc = (Neko3Archive)arc; + var nent = (Neko3Entry)entry; + var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); + Decrypt (data, data.Length, narc.Key, nent.Seed); + return new BinMemoryStream (data, entry.Name); + } + + void Decrypt (byte[] data, int length, byte[] key, ushort seed, bool init = false) + { + int count = length / 4; + unsafe + { + fixed (byte* data8 = data) + { + uint* data32 = (uint*)data8; + while (count --> 0) + { + uint s = *data32; + seed = (ushort)((seed + 0xC3) & 0x1FF); + uint d = s ^ LittleEndian.ToUInt32 (key, seed); + if (init) + seed += (ushort)s; + else + seed += (ushort)d; + *data32++ = d; + } + } + } + } + } +} diff --git a/ArcFormats/Nonono/ArcNPF.cs b/ArcFormats/Nonono/ArcNPF.cs index 745a545c..5efcd794 100644 --- a/ArcFormats/Nonono/ArcNPF.cs +++ b/ArcFormats/Nonono/ArcNPF.cs @@ -34,6 +34,24 @@ namespace GameRes.Formats.Nonono public int Seed; } + internal class NpfArchive : ArcFile + { + public readonly IRandomGenerator KeyGenerator; + + public NpfArchive (ArcView arc, ArchiveFormat impl, ICollection dir, IRandomGenerator rnd) + : base (arc, impl, dir) + { + KeyGenerator = rnd; + } + } + + internal interface IRandomGenerator + { + void SRand (int seed); + + int Rand (); + } + [Export(typeof(ArchiveFormat))] public class NpfOpener : ArchiveFormat { @@ -49,8 +67,28 @@ namespace GameRes.Formats.Nonono { if (file.View.ReadInt32 (4) != 4 || file.View.ReadInt32 (8) != 1) return null; + + foreach (var rnd in GetGenerators()) + { + var dir = ReadIndex (file, rnd); + if (dir != null) + { + return new NpfArchive (file, this, dir, rnd); + } + } + return null; + } + + internal IEnumerable GetGenerators () + { + yield return new RandomGenerator1 (DefaultSeed); + yield return new RandomGenerator2 (DefaultSeed); + } + + List ReadIndex (ArcView file, IRandomGenerator rnd) + { var header = file.View.ReadBytes (12, 20); - var rnd = new RandomGenerator (DefaultSeed); +// rnd.SRand (DefaultSeed); // generator already seeded by GetGenerators() Decrypt (header, 0, header.Length, rnd); if (!header.AsciiEqual ("FAT ")) return null; @@ -84,16 +122,16 @@ namespace GameRes.Formats.Nonono pos += 20; name_pos += name_length; } - return new ArcFile (file, this, dir); + return dir; } public override Stream OpenEntry (ArcFile arc, Entry entry) { - var nent = entry as NpfEntry; - if (null == nent) - return base.OpenEntry (arc, entry); + var narc = (NpfArchive)arc; + var nent = (NpfEntry)entry; var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); - var rnd = new RandomGenerator (nent.Seed); + var rnd = narc.KeyGenerator; + rnd.SRand (nent.Seed); Decrypt (data, 0, data.Length, rnd); return new BinMemoryStream (data, entry.Name); } @@ -106,20 +144,20 @@ namespace GameRes.Formats.Nonono return new ImgXDecoder (input); } - internal void Decrypt (byte[] data, int pos, int count, RandomGenerator rnd) + internal void Decrypt (byte[] data, int pos, int count, IRandomGenerator rnd) { for (int i = 0; i < count; ++i) data[pos + i] ^= (byte)rnd.Rand(); } } - internal class RandomGenerator + internal class RandomGenerator1 : IRandomGenerator { int m_seed; const int DefaultSeed = 0x67895; - public RandomGenerator (int seed = DefaultSeed) + public RandomGenerator1 (int seed = DefaultSeed) { SRand (seed); } @@ -141,4 +179,30 @@ namespace GameRes.Formats.Nonono return m_seed; } } + + internal class RandomGenerator2 : IRandomGenerator + { + int m_seed1; + int m_seed2; + + const int DefaultSeed = 0x67895; + + public RandomGenerator2 (int seed = DefaultSeed) + { + SRand (seed); + } + + public void SRand (int seed) + { + m_seed1 = seed; + m_seed2 = ((seed >> 12) ^ (seed << 18)) - 0x579E2B8D; + } + + public int Rand () + { + int n = m_seed2 + ((m_seed1 >> 10) ^ (m_seed1 << 14)); + m_seed2 = n - 0x15633649 + ((m_seed2 >> 12) ^ (m_seed2 << 18)); + return m_seed2; + } + } } diff --git a/ArcFormats/Nonono/ImageIMGX.cs b/ArcFormats/Nonono/ImageIMGX.cs index 33a24db5..84b9452f 100644 --- a/ArcFormats/Nonono/ImageIMGX.cs +++ b/ArcFormats/Nonono/ImageIMGX.cs @@ -64,7 +64,12 @@ namespace GameRes.Formats.Nonono using (var input = new MemoryStream (bitmap, header_size, bitmap.Length - header_size)) { if (8 == m_info.BPP) - palette = ImageFormat.ReadPalette (input); + { + int num_colors = bitmap.ToInt32 (0x20); + if (0 == num_colors) + num_colors = 0x100; + palette = ImageFormat.ReadPalette (input, num_colors); + } input.Read (pixels, 0, pixels.Length); } PixelFormat format = 8 == m_info.BPP ? PixelFormats.Indexed8 diff --git a/ArcFormats/Properties/AssemblyInfo.cs b/ArcFormats/Properties/AssemblyInfo.cs index a685200d..194f047b 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.2.48.2176")] -[assembly: AssemblyFileVersion ("1.2.48.2176")] +[assembly: AssemblyVersion ("1.2.48.2200")] +[assembly: AssemblyFileVersion ("1.2.48.2200")] diff --git a/ArcFormats/Properties/Settings.Designer.cs b/ArcFormats/Properties/Settings.Designer.cs index c3674968..7cae9633 100644 --- a/ArcFormats/Properties/Settings.Designer.cs +++ b/ArcFormats/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace GameRes.Formats.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -801,5 +801,17 @@ namespace GameRes.Formats.Properties { this["SJDatTitle"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("932")] + public int AFAEncodingCP { + get { + return ((int)(this["AFAEncodingCP"])); + } + set { + this["AFAEncodingCP"] = value; + } + } } } diff --git a/ArcFormats/Properties/Settings.settings b/ArcFormats/Properties/Settings.settings index c5258ce6..4b4c6753 100644 --- a/ArcFormats/Properties/Settings.settings +++ b/ArcFormats/Properties/Settings.settings @@ -197,5 +197,8 @@ + + 932 + \ No newline at end of file diff --git a/ArcFormats/RPM/ArcARC.cs b/ArcFormats/RPM/ArcARC.cs index fb8bfb2d..67be4eb1 100644 --- a/ArcFormats/RPM/ArcARC.cs +++ b/ArcFormats/RPM/ArcARC.cs @@ -84,6 +84,9 @@ namespace GameRes.Formats.Rpm /// Minimum entry length across all possible archive schemes. const int MinEntryLength = 0x24; + // largest size should be first + static readonly int[] PossibleNameSizes = new[] { 0x20, 0x18 }; + public override ArcFile TryOpen (ArcView file) { int count = file.View.ReadInt32 (0); @@ -94,7 +97,7 @@ namespace GameRes.Formats.Rpm return null; var index_reader = new ArcIndexReader (file, count, is_compressed != 0); - var scheme = index_reader.GuessScheme (8, new int[] { 0x20, 0x18 }); + var scheme = index_reader.GuessScheme (8, PossibleNameSizes); // additional checks to avoid dialog popup on false positives if (null == scheme && KnownSchemes.Count > 0 && file.Name.HasExtension (".arc")) { diff --git a/ArcFormats/Seraphim/ArcArchAngel.cs b/ArcFormats/Seraphim/ArcArchAngel.cs index 8b74130f..3618e765 100644 --- a/ArcFormats/Seraphim/ArcArchAngel.cs +++ b/ArcFormats/Seraphim/ArcArchAngel.cs @@ -28,6 +28,9 @@ using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; +// [960920][Petit] Trouble Outsiders +// [980220][Euphony Production] Happening Journey + namespace GameRes.Formats.ArchAngel { [Export(typeof(ArchiveFormat))] @@ -44,7 +47,7 @@ namespace GameRes.Formats.ArchAngel ContainedFormats = new[] { "CB" }; } - static readonly string[] DefaultSections = { "image", "script", null }; + static readonly string[] DefaultSections = { "image", "script", "" }; public override ArcFile TryOpen (ArcView file) { @@ -54,13 +57,7 @@ namespace GameRes.Formats.ArchAngel int file_count = file.View.ReadInt16 (0); if (!IsSaneCount (file_count)) return null; - uint index_pos = 2; - var size_table = new uint[file_count]; - for (int i = 0; i < file_count; ++i) - { - size_table[i] = file.View.ReadUInt32 (index_pos); - index_pos += 4; - } + long index_pos = 2 + 4 * file_count; var section_table = new SortedDictionary(); uint min_offset = (uint)file.MaxOffset; while (index_pos + 6 <= min_offset) @@ -76,26 +73,34 @@ namespace GameRes.Formats.ArchAngel } var dir = new List (file_count); int section_num = 0; + Func get_type; + if (section_table.Count == DefaultSections.Length) + get_type = () => DefaultSections[section_num]; + else + get_type = () => section_num > 0 ? "image" : ""; foreach (var section in section_table) { int i = section.Key; uint base_offset = section.Value; do { - uint size = size_table[i]; - var entry = new PackedEntry { - Name = string.Format ("{0}-{1:D6}", section_num, i), - Offset = base_offset, - Size = size, - }; - if (!entry.CheckPlacement (file.MaxOffset)) - return null; - if (section_num < DefaultSections.Length && DefaultSections[section_num] != null) - entry.Type = DefaultSections[section_num]; - if ("script" == entry.Type) - entry.IsPacked = true; - dir.Add (entry); - base_offset += size; + uint size = file.View.ReadUInt32 (2 + i * 4); + if (size > 0) + { + var entry = new PackedEntry + { + Name = string.Format("{0}-{1:D6}", section_num, i), + Type = get_type(), + Offset = base_offset, + Size = size, + }; + if (!entry.CheckPlacement(file.MaxOffset)) + return null; + if ("script" == entry.Type) + entry.IsPacked = true; + dir.Add(entry); + base_offset += size; + } ++i; } while (i < file_count && !section_table.ContainsKey (i)); diff --git a/ArcFormats/Seraphim/ArcSCN.cs b/ArcFormats/Seraphim/ArcSCN.cs index 304c6bac..834d684d 100644 --- a/ArcFormats/Seraphim/ArcSCN.cs +++ b/ArcFormats/Seraphim/ArcSCN.cs @@ -85,6 +85,14 @@ namespace GameRes.Formats.Seraphim { input = arc.File.CreateStream (entry.Offset+4, entry.Size-4); return new ZLibStream (input.AsStream, CompressionMode.Decompress); + /* + using (var compr = new ZLibStream (input.AsStream, CompressionMode.Decompress)) + using (var bin = new BinaryStream (compr, entry.Name)) + { + var data = LzDecompress (bin); + return new BinMemoryStream (data, entry.Name); + } + */ } input = arc.File.CreateStream (entry.Offset, entry.Size); if (signature < 4 || 0 != (signature & 0xFF000000)) @@ -141,4 +149,72 @@ namespace GameRes.Formats.Seraphim return data; } } + + [Export(typeof(ArchiveFormat))] + public class Scn95Opener : ArchiveFormat + { + public override string Tag { get { return "SCN/ARCH"; } } + public override string Description { get { return "Archangel engine scripts archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public Scn95Opener () + { + Extensions = new[] { "dat" }; + } + + public override ArcFile TryOpen (ArcView file) + { + if (!VFS.IsPathEqualsToFileName (file.Name, "SCNPAC.DAT")) + return null; + uint offset = file.View.ReadUInt32 (0); + int count = (int)offset / 4; + if (offset >= file.MaxOffset || !IsSaneCount (count)) + return null; + + int index_offset = 4; + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + uint size = file.View.ReadUInt32 (index_offset); + if (0 == size) + return null; + var entry = new Entry { + Name = i.ToString ("D5"), + Type = "script", + Offset = offset + 4, + Size = size, + }; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + offset += size; + index_offset += 4; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + IBinaryStream input = arc.File.CreateStream (entry.Offset, entry.Size); + if (input.Signature < 4 || 0 != (input.Signature & 0xFF000000)) + { + return input.AsStream; + } + try + { + var data = ScnOpener.LzDecompress (input); + return new BinMemoryStream (data, entry.Name); + } + catch + { + return arc.File.CreateStream (entry.Offset, entry.Size); + } + finally + { + input.Dispose(); + } + } + } } diff --git a/ArcFormats/Seraphim/ArcSeraph.cs b/ArcFormats/Seraphim/ArcSeraph.cs index 7d2408b8..dcbc0e8f 100644 --- a/ArcFormats/Seraphim/ArcSeraph.cs +++ b/ArcFormats/Seraphim/ArcSeraph.cs @@ -120,6 +120,8 @@ namespace GameRes.Formats.Seraphim List ReadIndex (ArcView file, long index_offset, long max_offset) { + if (index_offset >= max_offset) + return null; int base_count = file.View.ReadInt32 (index_offset); int file_count = file.View.ReadInt32 (index_offset + 4); index_offset += 8; @@ -220,7 +222,9 @@ namespace GameRes.Formats.Seraphim { uint width = input.ReadUInt16(); uint height = input.ReadUInt16(); - if (width > 0x4100 || 0 == width || 0 == height || width * height * 3 + 4 != input.Length) + uint plane_size = width * height; + uint total_size = (uint)(input.Length - 4); + if (width > 0x4100 || 0 == width || 0 == height || (total_size % plane_size) != 0) { input.Position = 0; return new ImageFormatDecoder (input); diff --git a/ArcFormats/Seraphim/ArcVoice.cs b/ArcFormats/Seraphim/ArcVoice.cs index 1edf5606..e3204ab6 100644 --- a/ArcFormats/Seraphim/ArcVoice.cs +++ b/ArcFormats/Seraphim/ArcVoice.cs @@ -47,7 +47,7 @@ namespace GameRes.Formats.Seraphim Extensions = new string[] { "dat" }; } - static readonly Regex VoiceRe = new Regex (@"^Voice\d\.dat$", RegexOptions.IgnoreCase); + static readonly Regex VoiceRe = new Regex (@"^Voice(?:\d|pac)\.dat$", RegexOptions.IgnoreCase); public override ArcFile TryOpen (ArcView file) { diff --git a/ArcFormats/Seraphim/ImageSeraph.cs b/ArcFormats/Seraphim/ImageSeraph.cs index 99a87887..9aabea24 100644 --- a/ArcFormats/Seraphim/ImageSeraph.cs +++ b/ArcFormats/Seraphim/ImageSeraph.cs @@ -47,12 +47,15 @@ namespace GameRes.Formats.Seraphim public SeraphCfImage () { - Extensions = new string[] { "cts" }; + Signatures = new [] { 0x4643u, 0x024643u, 0x044643u, 0x074643u, 0x094643u, 0x144643u, 0u }; + Extensions = new [] { "cts" }; } public override ImageMetaData ReadMetaData (IBinaryStream stream) { var header = stream.ReadHeader (0x10); + if ('C' != header[0] || 'F' != header[1] || 0 != header[3]) + return null; int packed_size = header.ToInt32 (12); if (packed_size <= 0 || packed_size > stream.Length-0x10) return null; diff --git a/ArcFormats/Sohfu/ArcSKA.cs b/ArcFormats/Sohfu/ArcSKA.cs new file mode 100644 index 00000000..0bca645f --- /dev/null +++ b/ArcFormats/Sohfu/ArcSKA.cs @@ -0,0 +1,139 @@ +//! \file ArcSKA.cs +//! \date 2022 Jun 12 +//! \brief Sohfu resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.Sohfu +{ + [Export(typeof(ArchiveFormat))] + public class SkaOpener : ArchiveFormat + { + public override string Tag { get { return "SKA/SOHFU"; } } + public override string Description { get { return "Sohfu resource archive"; } } + public override uint Signature { get { return 0x32465049; } } // 'IPF2' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + int count = file.View.ReadInt32 (4); + if (!IsSaneCount (count)) + return null; + + uint index_pos = 8; + var name_buffer = new byte[0x10]; + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + file.View.Read (index_pos, name_buffer, 0, 0x10); + int name_len = 0; + while (name_len < name_buffer.Length && name_buffer[name_len] != 0) + ++name_len; + var name = Encodings.cp932.GetString (name_buffer, 0, name_len); + ++name_len; + string ext = null; + if (name_len < 0x10) + ext = Binary.GetCString (name_buffer, name_len, 0x10 - name_len); + if (!string.IsNullOrEmpty (ext)) + name = Path.ChangeExtension (name, ext); + var entry = Create (name); + entry.Offset = file.View.ReadUInt32 (index_pos+0x10); + entry.Size = file.View.ReadUInt32 (index_pos+0x14); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + index_pos += 0x18; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pent = (PackedEntry)entry; + var input = arc.File.CreateStream (entry.Offset, entry.Size); + if (!pent.IsPacked) + { + if (input.Signature != 0x4238534C) // 'LS8B' + return input; + pent.IsPacked = true; + pent.UnpackedSize = arc.File.View.ReadUInt32 (pent.Offset+4); + } + using (input) + { + var data = new byte[pent.UnpackedSize]; + input.Position = 0xC; + LzssUnpack (input, data); + return new BinMemoryStream (data); + } + } + + void LzssUnpack (IBinaryStream input, byte[] output) + { + byte[] frame = new byte[0x1000]; + int frame_pos = 0xFFF; + const int frame_mask = 0xFFF; + int ctl = 1; + int dst = 0; + while (dst < output.Length) + { + if (1 == ctl) + { + ctl = input.ReadByte(); + if (-1 == ctl) + break; + ctl |= 0x100; + } + if (0 == (ctl & 1)) + { + int b = input.ReadByte(); + if (-1 == b) + break; + frame[++frame_pos & frame_mask] = (byte)b; + output[dst++] = (byte)b; + } + else + { + int lo = input.ReadByte(); + if (-1 == lo) + break; + int hi = input.ReadByte(); + if (-1 == hi) + break; + int offset = hi << 4 | lo >> 4; + for (int count = 3 + (lo & 0xF); count != 0; --count) + { + byte v = frame[(offset + frame_pos++ - 0xFFF) & frame_mask]; + frame[frame_pos & frame_mask] = v; + output[dst++] = v; + } + } + ctl >>= 1; + } + } + } +} diff --git a/ArcFormats/Sohfu/ImageDTL.cs b/ArcFormats/Sohfu/ImageDTL.cs new file mode 100644 index 00000000..5464288b --- /dev/null +++ b/ArcFormats/Sohfu/ImageDTL.cs @@ -0,0 +1,146 @@ +//! \file ImageDTL.cs +//! \date 2022 Jun 12 +//! \brief Sohfu image format; +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; + +namespace GameRes.Formats.Sohfu +{ + internal class DtlMetaData : ImageMetaData + { + public int Stride; + } + + [Export(typeof(ImageFormat))] + public class DtlFormat : ImageFormat + { + public override string Tag { get { return "DTL/SOHFU"; } } + public override string Description { get { return "Sohfu image format"; } } + public override uint Signature { get { return 0x5F4C5444; } } // 'DTL_' + + public DtlFormat () + { + Extensions = new[] { "ls8b", "ls8" }; + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x18); + int bpp = header.ToInt32 (16); + if (bpp != 24 && bpp != 32 && bpp != 8 && bpp != 4) + return null; + return new DtlMetaData + { + Width = header.ToUInt32 (8), + Height = header.ToUInt32 (12), + BPP = bpp, + Stride = header.ToInt32 (20), + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (DtlMetaData)info; + file.Position = 0x18; + var pixels = file.ReadBytes (meta.Stride * meta.iHeight); + PixelFormat format; + if (24 == meta.BPP) + format = PixelFormats.Bgr24; + else if (32 == meta.BPP) + format = PixelFormats.Bgra32; + else if (4 == meta.BPP) + format = PixelFormats.Gray4; + else + format = PixelFormats.Gray8; + return ImageData.Create (meta, format, null, pixels, meta.Stride); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("DtlFormat.Write not implemented"); + } + } + + [Export(typeof(ImageFormat))] + public class DtlcFormat : ImageFormat + { + public override string Tag { get { return "DTLC/SOHFU"; } } + public override string Description { get { return "Sohfu image format"; } } + public override uint Signature { get { return 0x434C5444; } } // 'DTLC' + + public DtlcFormat () + { + Extensions = new[] { "ls8b", "ls8" }; + Signatures = new[] { 0x434C5444u, 0x414C5444u }; // 'DTLA' + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x18); + int bpp = header.ToInt32 (16); + if (bpp != 24 && bpp != 32) + return null; + return new DtlMetaData + { + Width = header.ToUInt32 (8), + Height = header.ToUInt32 (12), + BPP = bpp, + Stride = header.ToInt32 (20), + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (DtlMetaData)info; +// var lineBuffer = new int[meta.iHeight][]; + file.Position = 0x18; + for (int y = 0; y < meta.iHeight; ++y) + { + int n = file.ReadInt32(); +// lineBuffer[y] = new int[n * 2]; + for (int i = 0; i < n; ++i) + { +// lineBuffer[y][i*2] = file.ReadInt32(); // x +// lineBuffer[y][i*2+1] = file.ReadInt32(); // number of pixels + file.ReadInt32(); + file.ReadInt32(); + } + } + var pixels = file.ReadBytes (meta.Stride * meta.iHeight); + PixelFormat format; + if (24 == meta.BPP) + format = PixelFormats.Bgr24; + else + format = PixelFormats.Bgra32; + return ImageData.Create (meta, format, null, pixels, meta.Stride); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("DtlcFormat.Write not implemented"); + } + } +} diff --git a/ArcFormats/Tanaka/ArcBMX.cs b/ArcFormats/Tanaka/ArcBMX.cs index 87546767..d815c4df 100644 --- a/ArcFormats/Tanaka/ArcBMX.cs +++ b/ArcFormats/Tanaka/ArcBMX.cs @@ -37,6 +37,11 @@ namespace GameRes.Formats.Will public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } + public BmxOpener () + { + ContainedFormats = new[] { "BC" }; + } + public override ArcFile TryOpen (ArcView file) { uint total_size = file.View.ReadUInt32 (0); @@ -48,34 +53,29 @@ namespace GameRes.Formats.Will var dir = new List (count); uint index_offset = 0x10; - uint next_offset = file.View.ReadUInt32 (index_offset+0x1C); for (int i = 0; i < count; ++i) { var name = file.View.ReadString (index_offset, 0x1C); if (0 == name.Length) break; - index_offset += 0x20; var entry = FormatCatalog.Instance.Create (name); - entry.Offset = next_offset; - if (i+1 < count) - { - next_offset = file.View.ReadUInt32 (index_offset+0x1C); - if (0 == next_offset) - next_offset = (uint)file.MaxOffset; - } - else - { - next_offset = (uint)file.MaxOffset; - } - entry.Size = (uint)(next_offset - entry.Offset); - if (!entry.CheckPlacement (file.MaxOffset)) - return null; + entry.Offset = file.View.ReadUInt32 (index_offset+0x1C); if (string.IsNullOrEmpty (entry.Type)) entry.Type = "image"; dir.Add (entry); + index_offset += 0x20; } if (0 == dir.Count) return null; + long last_offset = file.MaxOffset; + for (int i = dir.Count - 1; i >= 0; --i) + { + var entry = dir[i]; + entry.Size = (uint)(last_offset - entry.Offset); + last_offset = entry.Offset; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + } return new ArcFile (file, this, dir); } } diff --git a/ArcFormats/Tanaka/ArcMBF.cs b/ArcFormats/Tanaka/ArcMBF.cs index 7a1ac4c4..b214d866 100644 --- a/ArcFormats/Tanaka/ArcMBF.cs +++ b/ArcFormats/Tanaka/ArcMBF.cs @@ -40,6 +40,7 @@ namespace GameRes.Formats.Will public MbfOpener () { Signatures = new uint[] { 0x3046424D, 0x3146424D }; + ContainedFormats = new[] { "BC" }; } public override ArcFile TryOpen (ArcView file) diff --git a/ArcFormats/Tanaka/ArcVPK.cs b/ArcFormats/Tanaka/ArcVPK.cs index d43588b0..a25c56d0 100644 --- a/ArcFormats/Tanaka/ArcVPK.cs +++ b/ArcFormats/Tanaka/ArcVPK.cs @@ -43,6 +43,7 @@ namespace GameRes.Formats.Will { Extensions = new string[] { "vpk" }; Signatures = new uint[] { 0x314B5056, 0x304B5056 }; + ContainedFormats = new[] { "WAV" }; } public override ArcFile TryOpen (ArcView file) diff --git a/ArcFormats/Tanaka/ArcWSM.cs b/ArcFormats/Tanaka/ArcWSM.cs index e4f5e6c8..ecaa7ff4 100644 --- a/ArcFormats/Tanaka/ArcWSM.cs +++ b/ArcFormats/Tanaka/ArcWSM.cs @@ -43,6 +43,7 @@ namespace GameRes.Formats.Will { Extensions = new string[] { "wsm" }; Signatures = new uint[] { 0x324D5357, 0x334D5357 }; + ContainedFormats = new[] { "WAV" }; } public override ArcFile TryOpen (ArcView file) @@ -71,6 +72,7 @@ namespace GameRes.Formats.Will dir.Add (entry); } int index_offset = 0; + var names = new HashSet(); for (int i = 0; i < count; ++i) { int entry_pos = index.ToInt32 (index_offset); @@ -83,8 +85,20 @@ namespace GameRes.Formats.Will int entry_idx = index[entry_pos+3]; if (entry_idx >= dir.Count) return null; + if (0 == entry_idx) + entry_idx = i; var entry = dir[entry_idx]; - entry.Name = string.Format ("{0:D2}_{1}.wav", entry_idx, name); + entry.Name = name + ".wav"; + names.Add (entry.Name); + } + if (names.Count != dir.Count) + { + // make filenames unique by prepending index number + for (int i = 0; i < dir.Count; ++i) + { + var entry = dir[i]; + entry.Name = string.Format("{0:D2}_{1}", i, entry.Name); + } } return new ArcFile (file, this, dir); } diff --git a/ArcFormats/TechGian/ArcBIN.cs b/ArcFormats/TechGian/ArcBIN.cs new file mode 100644 index 00000000..411dce33 --- /dev/null +++ b/ArcFormats/TechGian/ArcBIN.cs @@ -0,0 +1,122 @@ +//! \file ArcBIN.cs +//! \date 2023 Aug 09 +//! \brief Tech Gian Archive +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using GameRes.Formats.Eagls; +using GameRes.Utility; + +// [121102][Tech Gian Archive] Hanafuda Market Totsugeki! Tonari no Kanban Musume + +namespace GameRes.Formats.TechGian +{ + internal class RfilEntry : Entry + { + public int EncryptionMethod; + + public bool IsEncrypted { + get { return EncryptionMethod == 1 || EncryptionMethod == 2 || EncryptionMethod == 4; } + } + } + + [Export(typeof(ArchiveFormat))] + public class BinOpener : ArchiveFormat + { + public override string Tag { get { return "BIN/RFIL"; } } + public override string Description { get { return "Tech Gian archive"; } } + public override uint Signature { get { return 0x4C494652; } } // 'RFIL' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + int count = file.View.ReadInt32 (8); + if (!IsSaneCount (count)) + return null; + bool is_encrypted = file.View.ReadInt32 (12) == 1234; + long index_pos = 0x10; + var buffer = new byte[0x40]; + var rnd = new CRuntimeRandomGenerator(); + rnd.SRand (0); + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + file.View.Read (index_pos, buffer, 0, 0x40); + if (is_encrypted) + DecryptRand (buffer, 0, 0x40, rnd); + var name = Binary.GetCString (buffer, 0, 0x30); + var entry = Create (name); + entry.Offset = buffer.ToUInt32 (0x34); + entry.Size = buffer.ToUInt32 (0x38); + entry.EncryptionMethod = buffer.ToInt32 (0x3C); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + index_pos += 0x40; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var rent = (RfilEntry)entry; + if (!rent.IsEncrypted) + return base.OpenEntry (arc, entry); + var data = arc.File.View.ReadBytes (rent.Offset, rent.Size); + switch (rent.EncryptionMethod) + { + case 1: + DecryptData (data, 0, data.Length); + break; + case 2: + if (data.Length > 0) + DecryptData (data, 0, (data.Length - 1) / 100 + 1); + break; + case 4: + DecryptData (data, 0, Math.Min (1024, data.Length)); + break; + } + return new BinMemoryStream (data, entry.Name); + } + + internal static void DecryptData (byte[] data, int pos, int length) + { + while (length --> 0) + { + data[pos++] ^= 0x7F; + } + } + + internal static void DecryptRand (byte[] data, int pos, int length, IRandomGenerator rnd) + { + while (length --> 0) + { + data[pos++] ^= (byte)rnd.Rand(); + } + } + } +} diff --git a/ArcFormats/TechnoBrain/ImageIPF.cs b/ArcFormats/TechnoBrain/ImageIPF.cs index d0cb670f..af07130f 100644 --- a/ArcFormats/TechnoBrain/ImageIPF.cs +++ b/ArcFormats/TechnoBrain/ImageIPF.cs @@ -93,7 +93,7 @@ namespace GameRes.Formats.TechnoBrain if (0x20706D62 != file.ReadInt32()) // 'bmp ' return false; int bmp_size = file.ReadInt32(); - if (bmp_size <= 0x20) + if (bmp_size < 0x1C) return false; info.BmpOffset = file.Position + 0x18; info.Width = file.ReadUInt16(); diff --git a/ArcFormats/Unity/Asset.cs b/ArcFormats/Unity/Asset.cs index f49db1a4..3922a0d7 100644 --- a/ArcFormats/Unity/Asset.cs +++ b/ArcFormats/Unity/Asset.cs @@ -93,8 +93,9 @@ namespace GameRes.Formats.Unity for (int i = 0; i < count; ++i) { input.Align(); + var file_id = input.ReadInt32(); var id = input.ReadId(); - m_adds[id] = input.ReadInt32(); + m_adds[id] = file_id; } } if (Format >= 6) @@ -353,8 +354,11 @@ namespace GameRes.Formats.Unity { int count = reader.ReadInt32(); int buffer_bytes = reader.ReadInt32(); - var node_data = reader.ReadBytes (24 * count); + int node_size = m_format >= 18 ? 32 : 24; + var node_data = reader.ReadBytes (node_size * count); m_data = reader.ReadBytes (buffer_bytes); + if (m_format >= 21) + reader.Skip (4); var parents = new Stack(); parents.Push (this); @@ -384,6 +388,8 @@ namespace GameRes.Formats.Unity current.Size = buf.ReadInt32(); current.Index = buf.ReadUInt32(); current.Flags = buf.ReadInt32(); + if (m_format >= 18) + buf.ReadInt64(); } } } diff --git a/ArcFormats/Unity/Texture2D.cs b/ArcFormats/Unity/Texture2D.cs index 7382a1cf..57a74c8a 100644 --- a/ArcFormats/Unity/Texture2D.cs +++ b/ArcFormats/Unity/Texture2D.cs @@ -104,13 +104,42 @@ namespace GameRes.Formats.Unity Load2021 (reader); return; } - if (type.Version != "2017.3.1f1") + if (type.Version != "2017.3.1f1" && type.Version != "2019.3.0f1" && type.Version != "2017.4.3f1") { Load (reader); if (0 == m_DataLength && type.Version.StartsWith ("2017.")) // "2017.2.0f3" || "2017.1.1p1" reader.ReadInt64(); return; } + // type hash = [1E 87 D8 2D 4F D0 58 50 9A 3C 78 66 DB 0E 73 56] + m_Name = reader.ReadString(); + reader.Align(); + reader.ReadInt32(); // m_ForcedFallbackFormat + reader.ReadInt32(); // m_DownscaleFallback + m_Width = reader.ReadInt32(); + m_Height = reader.ReadInt32(); + m_CompleteImageSize = reader.ReadInt32(); + m_TextureFormat = (TextureFormat)reader.ReadInt32(); + m_MipCount = reader.ReadInt32(); + m_IsReadable = reader.ReadBool(); + reader.Align(); + if ("2019.3.0f1" == type.Version) // type hash = [EE 6C 40 81 7D 29 51 92 9C DB 4F 5A 60 87 4F 5D] + reader.ReadInt32(); // m_StreamingMipmapsPriority + m_ImageCount = reader.ReadInt32(); + m_TextureDimension = reader.ReadInt32(); + m_FilterMode = reader.ReadInt32(); + m_Aniso = reader.ReadInt32(); + m_MipBias = reader.ReadFloat(); + m_WrapMode = reader.ReadInt32(); // m_WrapU + reader.ReadInt32(); // m_WrapV + reader.ReadInt32(); // m_WrapW + reader.ReadInt32(); // m_LightmapFormat + m_ColorSpace = reader.ReadInt32(); + m_DataLength = reader.ReadInt32(); + } + + public void Load2017 (AssetReader reader) + { m_Name = reader.ReadString(); reader.Align(); reader.ReadInt32(); // m_ForcedFallbackFormat diff --git a/ArcFormats/Winters/ArcCFP.cs b/ArcFormats/Winters/ArcCFP.cs new file mode 100644 index 00000000..8d525127 --- /dev/null +++ b/ArcFormats/Winters/ArcCFP.cs @@ -0,0 +1,75 @@ +//! \file ArcCFP.cs +//! \date 2022 May 17 +//! \brief Winters resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +// [110527][Winters] Kiss x 700 Kiss Tantei + +namespace GameRes.Formats.Winters +{ + [Export(typeof(ArchiveFormat))] + public class CfpOpener : ArchiveFormat + { + public override string Tag { get { return "CFP/CAPYBARA"; } } + public override string Description { get { return "Winters resource archive"; } } + public override uint Signature { get { return 0x59504143; } } // 'CAPYBARA DAT 002' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + if (!file.View.AsciiEqual (0, "CAPYBARA DAT 002")) + return null; + uint names_offset = file.View.ReadUInt32 (0x14); + uint names_length = file.View.ReadUInt32 (0x18); + uint index_offset = 0x20; + var dir = new List(); + using (var names = file.CreateStream (names_offset, names_length)) + using (var index = new StreamReader (names, Encodings.cp932)) + { + string name; + while (index_offset < names_offset && (name = index.ReadLine()) != null) + { + if (name.Length > 0) + { + var entry = FormatCatalog.Instance.Create (name); + entry.Offset = file.View.ReadUInt32 (index_offset); + entry.Size = file.View.ReadUInt32 (index_offset+4); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + index_offset += 0xC; + } + } + if (0 == dir.Count) + return null; + return new ArcFile (file, this, dir); + } + } +} diff --git a/ArcFormats/Xuse/ArcWAG.cs b/ArcFormats/Xuse/ArcWAG.cs index 03b19be5..aee76a95 100644 --- a/ArcFormats/Xuse/ArcWAG.cs +++ b/ArcFormats/Xuse/ArcWAG.cs @@ -57,6 +57,7 @@ namespace GameRes.Formats.Xuse { Extensions = new string[] { "wag", "4ag", "004" }; Signatures = new uint[] { 0x40474157, 0x34464147 }; // 'GAF4' +// ContainedFormats = new [] { "PNG", "P/4AG" }; } public override ArcFile TryOpen (ArcView file) @@ -284,7 +285,7 @@ namespace GameRes.Formats.Xuse return entry; } - static readonly Regex DriveRe = new Regex (@"^(?:.+:)?\\+"); + static readonly Regex DriveRe = new Regex (@"^(?:.+:|\.\.)?\\+"); } } } diff --git a/ArcFormats/Xuse/ImageP.cs b/ArcFormats/Xuse/ImageP.cs new file mode 100644 index 00000000..265ea7a6 --- /dev/null +++ b/ArcFormats/Xuse/ImageP.cs @@ -0,0 +1,64 @@ +//! \file ImageP.cs +//! \date 2022 May 07 +//! \brief Obfuscated PNG file. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; + +namespace GameRes.Formats.Xuse +{ + [Export(typeof(ImageFormat))] + public class P4AGFormat : ImageFormat + { + public override string Tag { get { return "P/4AG"; } } + public override string Description { get { return "Xuse/Eternal obfuscated PNG image"; } } + public override uint Signature { get { return 0x0A0D474E; } } // 'NG\n\r' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + using (var input = OpenAsPng (file)) + return Png.ReadMetaData (input); + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + using (var input = OpenAsPng (file)) + return Png.Read (input, info); + } + + static readonly byte[] HeaderBytes = new byte[2] { PngFormat.HeaderBytes[0], PngFormat.HeaderBytes[1] }; + + internal IBinaryStream OpenAsPng (IBinaryStream file) + { + var input = new PrefixStream (HeaderBytes, file.AsStream, true); + return new BinaryStream (input, file.Name); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("P4AGFormat.Write not implemented"); + } + } +} diff --git a/ArcFormats/Zyx/ImageXMG.cs b/ArcFormats/Zyx/ImageXMG.cs new file mode 100644 index 00000000..0002cbe1 --- /dev/null +++ b/ArcFormats/Zyx/ImageXMG.cs @@ -0,0 +1,142 @@ +//! \file ImageXMG.cs +//! \date 2022 Jun 19 +//! \brief ZyX image format. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Ikura +{ + [Export(typeof(ImageFormat))] + public class XmgFormat : ImageFormat + { + public override string Tag { get { return "XMG"; } } + public override string Description { get { return "ZyX image format"; } } + public override uint Signature { get { return 0; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + if (!file.Name.HasExtension (".xmg")) + return null; + var header = file.ReadBytes (12); + Decrypt (header); + if (header[2] != 0 || header[3] != 0) + return null; + int width = LittleEndian.ToInt16 (header, 4); + int height = LittleEndian.ToInt16 (header, 6); + if (width <= 0 || height <= 0) + return null; + return new ImageMetaData { + Width = (uint)width, + Height = (uint)height, + BPP = 8, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + file.Position = 12; + var palette_data = file.ReadBytes (0x300); + Decrypt (palette_data, (byte)(12 * 7)); + var palette = ConvertPalette (palette_data); + var pixels = new byte[info.iWidth * info.iHeight]; + int dst = 0; + for (int y = 0; y < info.iHeight; ++y) + { + int x = 0; + while (x < info.iWidth) + { + byte ctl = file.ReadUInt8(); + int offset; + int count; + if ((ctl & 0xC0) != 0) + { + if ((ctl & 0x80) != 0) + { + offset = -((ctl << 8 | file.ReadUInt8()) & 0xFFF) - 1; + count = (ctl & 0x70) >> 4; + if (count != 0) + count += 2; + else + count = file.ReadUInt8() + 10; + Binary.CopyOverlapped (pixels, dst + offset, dst, count); + } + else + { + count = ctl & 0x3F; + if (0 == count) + count = 64 + file.ReadUInt8(); + count += 1; + byte p = pixels[dst-1]; + for (int i = 0; i < count; ++i) + pixels[dst+i] = p; + } + } + else + { + count = ctl & 0x3F; + if (0 == count) + count = 64 + file.ReadUInt8(); + file.Read (pixels, dst, count); + } + x += count; + dst += count; + } + } + return ImageData.Create (info, PixelFormats.Indexed8, palette, pixels); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("xxxFormat.Write not implemented"); + } + + internal static BitmapPalette ConvertPalette (byte[] palette_data) + { + const int colors = 0x100; + var color_map = new Color[colors]; + int src = 0; + for (int i = 0; i < colors; ++i) + { + color_map[i] = Color.FromRgb (palette_data[src+1], palette_data[src+2], palette_data[src]); + src += 3; + } + return new BitmapPalette (color_map); + } + + internal static byte Decrypt (byte[] data, byte key = 0) + { + for (int i = 0; i < data.Length; ++i) + { + byte v = (byte)((data[i] - key) ^ 0xF3); + data[i] = v; + key += 7; + } + return key; + } + } +} diff --git a/ArcFormats/app.config b/ArcFormats/app.config index f2b7e940..9d9ed542 100644 --- a/ArcFormats/app.config +++ b/ArcFormats/app.config @@ -199,6 +199,9 @@ + + 932 + diff --git a/ArcFormats/elf/ImageG24.cs b/ArcFormats/elf/ImageG24.cs index 5e9d7024..6f868895 100644 --- a/ArcFormats/elf/ImageG24.cs +++ b/ArcFormats/elf/ImageG24.cs @@ -40,7 +40,7 @@ namespace GameRes.Formats.Elf public G24Format () { - Extensions = new string[] { "g24", "g16" }; + Extensions = new string[] { "g24", "g16", "g32" }; } public override ImageMetaData ReadMetaData (IBinaryStream input) @@ -57,7 +57,8 @@ namespace GameRes.Formats.Elf Height = (uint)h, OffsetX = x, OffsetY = y, - BPP = input.Name.HasExtension (".G16") ? 16 : 24 + BPP = input.Name.HasExtension (".G16") ? 16 + : input.Name.HasExtension (".G32") ? 32 : 24 }; } @@ -70,7 +71,9 @@ namespace GameRes.Formats.Elf { if (pixels.Length != reader.Read (pixels, 0, pixels.Length)) throw new InvalidFormatException(); - var format = 24 == info.BPP ? PixelFormats.Bgr24 : PixelFormats.Bgr555; + var format = 24 == info.BPP ? PixelFormats.Bgr24 + : 32 == info.BPP ? PixelFormats.Bgra32 + : PixelFormats.Bgr555; return ImageData.CreateFlipped (info, format, null, pixels, stride); } } diff --git a/ArcFormats/rUGP/ArcRIO.cs b/ArcFormats/rUGP/ArcRIO.cs index c8263ae3..0145da50 100644 --- a/ArcFormats/rUGP/ArcRIO.cs +++ b/ArcFormats/rUGP/ArcRIO.cs @@ -77,7 +77,13 @@ namespace GameRes.Formats.Rugp Size = node.Size }; if (!dir.Any()) - return null; + { + var box_ref = nodes.FirstOrDefault (n => n.ClassName == "CBoxOcean"); + if (null == box_ref) + return null; + var box = reader.ReadObject (box_ref); + nodes = reader.Arc.LoadArray.OfType(); + } return new ArcFile (file, this, dir.ToList()); } } @@ -307,7 +313,7 @@ namespace GameRes.Formats.Rugp public int GetObjectSchema () { int schema = m_objectSchema; - m_objectSchema = -1; +// m_objectSchema = -1; return schema; } @@ -329,9 +335,12 @@ namespace GameRes.Formats.Rugp public CObject ReadObject (COceanNode node) { + m_field_60 = false; var obj = CreateObject (node.Name); PopulateLoadArray(); m_input.Position = ((long)node.Offset << m_shift); +// if (node.Name != "CrelicUnitedGameProject") +// m_input.Seek (3, SeekOrigin.Current); int f1 = ReadByte() & 3; int f2 = ReadByte(); int f3 = ReadByte(); @@ -700,7 +709,7 @@ namespace GameRes.Formats.Rugp class_ref = LoadRuntimeClass (out schema); if (null == class_ref) throw new InvalidFormatException(); -// m_objectSchema = (int)schema; + m_objectSchema = (int)schema; m_LoadArray.Add (class_ref); } @@ -957,6 +966,7 @@ namespace GameRes.Formats.Rugp { "CrelicUnitedGameProject", new CObjectFactory() }, { "CStdb", new CObjectFactory() }, { "CObjectOcean", new CObjectFactory() }, + { "CBoxOcean", new CObjectFactory() }, }; } @@ -1351,11 +1361,74 @@ namespace GameRes.Formats.Rugp internal class CBoxOcean : CObject { - public CObject field_10; + public CObject field_10; + public CObject field_14; + public List field_18 = new List(); + public List field_118 = new List(); + public CObject field_198; + public List m_box_list = new List(); + + static CObject static_cui = null; public override void Deserialize (CRioArchive arc) { field_10 = arc.ReadRioReference ("CFrameBuffer"); + int schema = arc.GetObjectSchema(); + if (schema < 3) + { + for (int i = 0; i < 32; ++i) + { + var box = arc.ReadRioReference ("CBox"); + m_box_list.Add (box); + } + } + if (schema >= 2) + { + field_14 = arc.ReadRioReference ("CSbm"); + if (schema < 6) + { + field_18.Add (arc.ReadRioReference ("CSbm")); + } + else + { + int ref_count = 15; + int str_count = 0; + if (schema >= 7) + { + ref_count = 32; + str_count = 32; + } + for (int i = 0; i < ref_count; ++i) + { + field_18.Add (arc.ReadRioReference ("CSbm")); + } + for (int i = 0; i < str_count; ++i) + { + field_118.Add (arc.ReadString()); + } + } + field_198 = arc.ReadRioReference ("CUnitedMenu"); + if (schema >= 4) + { + ReadCui (arc); + if (schema >= 5) + { + var cui = arc.ReadRioReference ("CUI"); + if (cui != static_cui) + { + ReadCui (arc); + } + } + } + } + } + + void ReadCui (CRioArchive arc) + { + while (arc.ReadByte() != 0) + { + var cui = arc.ReadRioReference ("CUI"); + } } } diff --git a/Experimental/Properties/AssemblyInfo.cs b/Experimental/Properties/AssemblyInfo.cs index efd3d688..24593c56 100644 --- a/Experimental/Properties/AssemblyInfo.cs +++ b/Experimental/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.0.16.40")] -[assembly: AssemblyFileVersion ("1.0.16.40")] +[assembly: AssemblyVersion ("1.0.16.42")] +[assembly: AssemblyFileVersion ("1.0.16.42")] diff --git a/Experimental/RPGMaker/AudioRPGMV.cs b/Experimental/RPGMaker/AudioRPGMV.cs index a8820b79..7a629049 100644 --- a/Experimental/RPGMaker/AudioRPGMV.cs +++ b/Experimental/RPGMaker/AudioRPGMV.cs @@ -35,6 +35,11 @@ namespace GameRes.Formats.RPGMaker public override uint Signature { get { return 0x4D475052; } } // 'RPGMV' public override bool CanWrite { get { return false; } } + public RpgmvoAudio () + { + Extensions = new[] { "rpgmvo", "ogg_" }; + } + public override SoundInput TryOpen (IBinaryStream file) { var header = file.ReadHeader (0x14); diff --git a/Experimental/RPGMaker/ImageRPGMV.cs b/Experimental/RPGMaker/ImageRPGMV.cs index 5a01ca04..d65045ae 100644 --- a/Experimental/RPGMaker/ImageRPGMV.cs +++ b/Experimental/RPGMaker/ImageRPGMV.cs @@ -44,6 +44,11 @@ namespace GameRes.Formats.RPGMaker public override string Description { get { return "RPG Maker engine image format"; } } public override uint Signature { get { return 0x4D475052; } } // 'RPGMV' + public RpgmvpFormat () + { + Extensions = new string[] { "rpgmvp", "png_" }; + } + public override ImageMetaData ReadMetaData (IBinaryStream file) { var header = file.ReadHeader (0x14); @@ -149,6 +154,8 @@ namespace GameRes.Formats.RPGMaker var dir_name = Path.GetDirectoryName (filename); yield return Path.Combine (dir_name, @"..\..\data\System.json"); yield return Path.Combine (dir_name, @"..\..\..\www\data\System.json"); + yield return Path.Combine (dir_name, @"..\..\..\data\System.json"); + yield return Path.Combine (dir_name, @"..\..\..\..\data\System.json"); yield return Path.Combine (dir_name, @"..\data\System.json"); yield return Path.Combine (dir_name, @"data\System.json"); } diff --git a/GameRes/ImagePNG.cs b/GameRes/ImagePNG.cs index 24d7fc74..93deacc7 100644 --- a/GameRes/ImagePNG.cs +++ b/GameRes/ImagePNG.cs @@ -34,6 +34,7 @@ using System.Windows.Media; namespace GameRes { [Export(typeof(ImageFormat))] + [ExportMetadata("Priority", 100)] // makes PNG first format in list public class PngFormat : ImageFormat { public override string Tag { get { return "PNG"; } } diff --git a/GameRes/Properties/AssemblyInfo.cs b/GameRes/Properties/AssemblyInfo.cs index ae198900..ed61600f 100644 --- a/GameRes/Properties/AssemblyInfo.cs +++ b/GameRes/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.5.44.320")] -[assembly: AssemblyFileVersion ("1.5.44.320")] +[assembly: AssemblyVersion ("1.5.44.321")] +[assembly: AssemblyFileVersion ("1.5.44.321")] diff --git a/GameRes/ScriptText.cs b/GameRes/ScriptText.cs index 735ad88b..b2292d1b 100644 --- a/GameRes/ScriptText.cs +++ b/GameRes/ScriptText.cs @@ -30,12 +30,51 @@ namespace GameRes { public override string Type { get { return "script"; } } + public abstract bool IsScript (IBinaryStream file); + + public abstract Stream ConvertFrom (IBinaryStream file); + public abstract Stream ConvertBack (IBinaryStream file); + public abstract ScriptData Read (string name, Stream file); public abstract void Write (Stream file, ScriptData script); + + public static ScriptFormat FindFormat (IBinaryStream file) + { + foreach (var impl in FormatCatalog.Instance.FindFormats (file.Name, file.Signature)) + { + try + { + file.Position = 0; + if (impl.IsScript (file)) + return impl; + } + catch (System.OperationCanceledException) + { + throw; + } + catch { } + } + return null; + } } public abstract class GenericScriptFormat : ScriptFormat { + public override bool IsScript (IBinaryStream file) + { + return false; + } + + public override Stream ConvertFrom (IBinaryStream file) + { + return file.AsStream; + } + + public override Stream ConvertBack (IBinaryStream file) + { + return file.AsStream; + } + public override ScriptData Read (string name, Stream file) { throw new System.NotImplementedException(); diff --git a/Legacy/Airyu/ArcCHR.cs b/Legacy/Airyu/ArcCHR.cs index 8f8167e7..1a1eabb4 100644 --- a/Legacy/Airyu/ArcCHR.cs +++ b/Legacy/Airyu/ArcCHR.cs @@ -38,12 +38,23 @@ namespace GameRes.Formats.Airyu public override bool IsHierarchic { get { return false; } } public override bool CanWrite { get { return false; } } + static readonly uint[] ImageSizes = new[] { 0x96000u, 0x4B000u, 0x19000u }; + public override ArcFile TryOpen (ArcView file) { if (!file.Name.HasExtension (".chr")) return null; - int count = (int)(file.MaxOffset / 0x96000); - if (!IsSaneCount (count) || count * 0x96000 != file.MaxOffset) + int count = 0; + uint image_size = 1; + for (int i = 0; i < ImageSizes.Length; ++i) + { + image_size = ImageSizes[i]; + count = (int)(file.MaxOffset / image_size); + if (IsSaneCount (count) && count * image_size == file.MaxOffset) + break; + count = 0; + } + if (0 == count) return null; uint offset = 0; @@ -54,10 +65,10 @@ namespace GameRes.Formats.Airyu Name = i.ToString ("D5"), Type = "image", Offset = offset, - Size = 0x96000, + Size = image_size, }; dir.Add (entry); - offset += 0x96000; + offset += image_size; } return new ArcFile (file, this, dir); } @@ -65,21 +76,32 @@ namespace GameRes.Formats.Airyu public override IImageDecoder OpenImage (ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); - return new ChrImageDecoder (input); + return new ChrImageDecoder (input, entry.Size); } } internal class ChrImageDecoder : BinaryImageDecoder { - public ChrImageDecoder (IBinaryStream input) : base (input) + int m_image_size; + int m_stride; + + public ChrImageDecoder (IBinaryStream input, uint size) : base (input) { - Info = new ImageMetaData { Width = 640, Height = 480, BPP = 16 }; + m_image_size = (int)size; + switch (size) + { + case 0x19000: Info = new ImageMetaData { Width = 200, Height = 256, BPP = 16 }; break; + case 0x4B000: Info = new ImageMetaData { Width = 320, Height = 480, BPP = 16 }; break; + case 0x96000: Info = new ImageMetaData { Width = 640, Height = 480, BPP = 16 }; break; + default: throw new InvalidFormatException ("Invalid image size."); + } + m_stride = Info.iWidth * 2; } protected override ImageData GetImageData () { - var pixels = m_input.ReadBytes (0x96000); - return ImageData.CreateFlipped (Info, PixelFormats.Bgr555, null, pixels, 640*2); + var pixels = m_input.ReadBytes (m_image_size); + return ImageData.CreateFlipped (Info, PixelFormats.Bgr555, null, pixels, m_stride); } } } diff --git a/Legacy/BlackButterfly/ArcDAT.cs b/Legacy/BlackButterfly/ArcDAT.cs new file mode 100644 index 00000000..44d9fde8 --- /dev/null +++ b/Legacy/BlackButterfly/ArcDAT.cs @@ -0,0 +1,142 @@ +//! \file ArcDAT.cs +//! \date 2022 Nov 09 +//! \brief Black Butterfly resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.BlackButterfly +{ + [Export(typeof(ArchiveFormat))] + public class DatOpener : ArchiveFormat + { + public override string Tag { get { return "DAT/PITA"; } } + public override string Description { get { return "Black Butterfly resource archive"; } } + public override uint Signature { get { return 0x41544950; } } // 'PITA' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + int count = file.View.ReadInt32 (4); + if (!IsSaneCount (count)) + return null; + + uint index_pos = 0x10; + uint next_offset = file.View.ReadUInt32 (index_pos); + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + index_pos += 4; + var entry = new PackedEntry { + Name = string.Format ("{0:D5}.bmp", i), + Type = "image", + Offset = next_offset, + }; + next_offset = file.View.ReadUInt32 (index_pos); + entry.Size = (uint)(next_offset - entry.Offset); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pent = (PackedEntry)entry; + if (!pent.IsPacked) + { + pent.IsPacked = true; + pent.UnpackedSize = arc.File.View.ReadUInt32 (pent.Offset); + } + using (var input = arc.File.CreateStream (pent.Offset+4, pent.Size-4)) + { + var data = new byte[pent.UnpackedSize]; + Unpack (input, data); + return new BinMemoryStream (data, entry.Name); + } + } + + void Unpack (IBinaryStream input, byte[] output) + { + int dst = 0; + while (input.PeekByte() != -1) + { + byte ctl = input.ReadUInt8(); + if (0x7F == ctl) + { + if (input.PeekByte() == 0xFF) + break; + } + int count; + if (ctl <= 0x7F) + { + count = (ctl >> 2) + 2; + int offset = (ctl & 3) << 8 | input.ReadUInt8(); + offset = (offset ^ 0x3FF) + 1; + Binary.CopyOverlapped (output, dst - offset, dst, count); + dst += count; + } + else if (ctl > 0xFE) + { + count = input.ReadUInt8() + 32; + while (count --> 0) + output[dst++] = 0; + } + else if (ctl > 0xDF) + { + count = (ctl & 0x1F) + 1; + while (count --> 0) + output[dst++] = 0; + } + else if (ctl > 0xBF) + { + count = (ctl & 0x1F) + 2; + byte fill = input.ReadUInt8(); + while (count --> 0) + output[dst++] = fill; + } + else if (ctl > 0x9F) + { + count = (ctl & 0x1F) + 1; + while (count --> 0) + { + output[dst++] = 0; + output[dst++] = input.ReadUInt8(); + } + } + else + { + count = (ctl & 0x1F) + 1; + input.Read (output, dst, count); + dst += count; + } + } + } + } +} diff --git a/Legacy/CottonClub/ImageLMG.cs b/Legacy/CottonClub/ImageLMG.cs new file mode 100644 index 00000000..283fd7cd --- /dev/null +++ b/Legacy/CottonClub/ImageLMG.cs @@ -0,0 +1,204 @@ +//! \file ImageLMG.cs +//! \date 2023 Aug 07 +//! \brief Cotton Club encrypted image. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +// [071231][Cotton Club] Kureuta + +namespace GameRes.Formats.CottonClub +{ + public class LmgMetaData : ImageMetaData + { + public byte Method; + } + + [Export(typeof(ImageFormat))] + public class LmgFormat : ImageFormat + { + public override string Tag { get { return "LMG"; } } + public override string Description { get { return "Cotton Club encrypted image"; } } + public override uint Signature { get { return 0x03474D4C; } } // 'LMG' + + public LmgFormat () + { + Signatures = new uint[] { 0x03474D4C, 0x02474D4C, 0x01474D4C }; + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (12); + return new LmgMetaData { + Width = header.ToUInt32 (4), + Height = header.ToUInt32 (8), + BPP = header[3] == 2 ? 32 : 24, + Method = header[3], + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (LmgMetaData)info; + var data = new byte[file.Length - 12]; + file.Position = 12; + file.Read (data, 0, data.Length); + DecryptData (data, file.Name); + if (3 == meta.Method) + { + using (var input = new BinMemoryStream (data)) + { + var decoder = new JpegBitmapDecoder (input, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + var frame = decoder.Frames[0]; + frame.Freeze(); + return new ImageData (frame, info); + } + } + else if (2 == meta.Method) + { + var reader = new LmgReader (info, data); + data = reader.Unpack(); + return ImageData.Create (info, PixelFormats.Bgra32, null, data, reader.Stride); + } + else + { + return ImageData.Create (info, PixelFormats.Bgr24, null, data, info.iWidth * 3); + } + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("LmgFormat.Write not implemented"); + } + + internal void DecryptData (byte[] data, string filename) + { + filename = Path.GetFileName (filename).ToLowerInvariant(); + byte key = 0; + for (int i = 0; i < filename.Length; ++i) + { + key ^= (byte)filename[i]; + } + for (int i = 0; i < data.Length; ++i) + { + byte x = data[i]; + data[i] ^= key; + key = x; + } + } + } + + internal class LmgReader + { + byte[] m_data; + byte[] m_output; + int m_stride; + + public int Stride { get { return m_stride; } } + + public LmgReader (ImageMetaData info, byte[] data) + { + m_data = data; + m_stride = info.iWidth * 4; + m_output = new byte[m_stride * info.iHeight]; + } + + int m_src; + int m_dst; + + public byte[] Unpack () + { + m_src = 0; + m_dst = 0; + while (m_src+1 < m_data.Length) + { + byte alpha = m_data[m_src++]; + if (0xFF == alpha) + { + int length = GetLength16(); + for (int i = 0; i < length; ++i) + { + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = 0xFF; + } + } + else if (0 == alpha) + { + int length = GetLength16(); + m_dst += length * 4; + } + else + { + ReadARGB (alpha); + } + } + return m_output; + } + + void ReadARGB (byte alpha) + { + int length = GetLength8(); + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = alpha; + while (--length > 0) + { + alpha = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = m_data[m_src++]; + m_output[m_dst++] = alpha; + } + } + + int GetLength8 () + { + int i = 0; + while (m_data[m_src] == 0) + { + i += 0xFF; + ++m_src; + } + return i + m_data[m_src++]; + } + + int GetLength16 () + { + int i = 0; + while (m_data[m_src] == 0 && m_data[m_src+1] == 0) + { + i += 0xFFFF; + m_src += 2; + } + i += m_data.ToUInt16 (m_src); + m_src += 2; + return i; + } + } +} diff --git a/Legacy/Dice/ArcRLZ.cs b/Legacy/Dice/ArcRLZ.cs index d965ad63..81cdd0a2 100644 --- a/Legacy/Dice/ArcRLZ.cs +++ b/Legacy/Dice/ArcRLZ.cs @@ -28,6 +28,7 @@ using System.ComponentModel.Composition; using System.IO; // [000623][Marimo] Setsunai +// [010316][Evolution] Bukkake Tenshi Silky & Milky namespace GameRes.Formats.Dice { diff --git a/Legacy/DigitalMonkey/ArcDM.cs b/Legacy/DigitalMonkey/ArcDM.cs index e1a5050d..617beb07 100644 --- a/Legacy/DigitalMonkey/ArcDM.cs +++ b/Legacy/DigitalMonkey/ArcDM.cs @@ -30,6 +30,7 @@ using GameRes.Compression; // [030725][Digital Monkey] Kono Sora ga Tsuieru Toki ni // [041112][Yumesta] Seikon ~Kiba to Nie to Kyouki no Yakata~ +// [050325][Supple Entertainment] Dark: Shitsuraku no Shimai Ningyou namespace GameRes.Formats.DigitalMonkey { diff --git a/Legacy/Giga/ArcALL.cs b/Legacy/Giga/ArcALL.cs new file mode 100644 index 00000000..665f97ce --- /dev/null +++ b/Legacy/Giga/ArcALL.cs @@ -0,0 +1,2090 @@ +//! \file ArcALL.cs +//! \date 2022 May 07 +//! \brief Giga resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using GameRes.Utility; + +namespace GameRes.Formats.Giga +{ + [Export(typeof(ArchiveFormat))] + public class AllOpener : ArchiveFormat + { + public override string Tag { get { return "ALL/GIGA"; } } + public override string Description { get { return "Giga resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public AllOpener () + { + Extensions = new[] { "273" }; + ContainedFormats = new[] { "BMP", "DAT/GENERIC" }; + } + + public override ArcFile TryOpen (ArcView file) + { + var base_name = Path.GetFileName (file.Name); + List dir; + if (!FileMap273.TryGetValue (base_name, out dir) || 0 == dir.Count) + return null; + 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); + var data = new byte[pent.UnpackedSize]; + using (var input = arc.File.CreateStream (pent.Offset, pent.Size)) + LzssUnpack (input, data); + return new BinMemoryStream (data); + } + + internal static void LzssUnpack (IBinaryStream input, byte[] output) + { + int dst = 0; + int bitcount = input.ReadInt32(); + if (0 == bitcount) + { + input.Read (output, 0, output.Length); + return; + } + int bytecount = bitcount >> 3; + int bits = 8; + while (dst < output.Length) + { + do + { + int ctl = input.ReadUInt8(); + --bytecount; + for (int i = 0; i < bits; ++i) + { + if ((ctl & 1) != 0) + { + output[dst++] = input.ReadUInt8(); + } + else + { + int count = input.ReadUInt16(); + int offset = dst - (count & 0xFFF) - 1; + if ((count & 0xF000) != 0) + { + count = (count >> 12) + 2; + } + else + { + count = input.ReadUInt8() + 0x12; + } + Binary.CopyOverlapped (output, offset, dst, count); + dst += count; + } + ctl >>= 1; + } + } + while (bytecount > 0); + if (bitcount <= 0) + break; + bits = bitcount & 7; + bitcount = 0; + } + } + + static readonly Dictionary> FileMap273 = new Dictionary> (StringComparer.OrdinalIgnoreCase) + { + { + "ALLCHP.273", new List() { + new PackedEntry { Name = "ankei_a.chp", Type = "image", Offset = 0x0, UnpackedSize = 0x0C436, Size = 0x13C5, IsPacked = true }, + new PackedEntry { Name = "ankei_b.chp", Type = "image", Offset = 0x13C5, UnpackedSize = 0x8436, Size = 0x108C, IsPacked = true }, + new PackedEntry { Name = "ankei_c.chp", Type = "image", Offset = 0x2451, UnpackedSize = 0x0C436, Size = 0x136C, IsPacked = true }, + new PackedEntry { Name = "beem_a.chp", Type = "image", Offset = 0x37BD, UnpackedSize = 0x8436, Size = 0x0ED0, IsPacked = true }, + new PackedEntry { Name = "beem_b.chp", Type = "image", Offset = 0x468D, UnpackedSize = 0x8436, Size = 0x0CE6, IsPacked = true }, + new PackedEntry { Name = "beem_c.chp", Type = "image", Offset = 0x5373, UnpackedSize = 0x8436, Size = 0x0ED5, IsPacked = true }, + new PackedEntry { Name = "b_abel_a.chp", Type = "image", Offset = 0x6248, UnpackedSize = 0x78436, Size = 0x1E2BF, IsPacked = true }, + new PackedEntry { Name = "b_ann_a.chp", Type = "image", Offset = 0x24507, UnpackedSize = 0x0A8436, Size = 0x2B22D, IsPacked = true }, + new PackedEntry { Name = "b_ann_b.chp", Type = "image", Offset = 0x4F734, UnpackedSize = 0x0AC436, Size = 0x2B620, IsPacked = true }, + new PackedEntry { Name = "b_ann_c.chp", Type = "image", Offset = 0x7AD54, UnpackedSize = 0x0A4436, Size = 0x27C72, IsPacked = true }, + new PackedEntry { Name = "b_bal1_a.chp", Type = "image", Offset = 0x0A29C6, UnpackedSize = 0x3C436, Size = 0x104BB, IsPacked = true }, + new PackedEntry { Name = "b_bat_a.chp", Type = "image", Offset = 0x0B2E81, UnpackedSize = 0x34436, Size = 0x0A164, IsPacked = true }, + new PackedEntry { Name = "b_bat_b.chp", Type = "image", Offset = 0x0BCFE5, UnpackedSize = 0x34436, Size = 0x0A21F, IsPacked = true }, + new PackedEntry { Name = "b_bee1_a.chp", Type = "image", Offset = 0x0C7204, UnpackedSize = 0x64436, Size = 0x15DC1, IsPacked = true }, + new PackedEntry { Name = "b_bobe_a.chp", Type = "image", Offset = 0x0DCFC5, UnpackedSize = 0x38436, Size = 0x0D98F, IsPacked = true }, + new PackedEntry { Name = "b_bosc_a.chp", Type = "image", Offset = 0x0EA954, UnpackedSize = 0x20436, Size = 0x7562, IsPacked = true }, + new PackedEntry { Name = "b_cain_a.chp", Type = "image", Offset = 0x0F1EB6, UnpackedSize = 0x0A4436, Size = 0x28B09, IsPacked = true }, + new PackedEntry { Name = "b_cain_b.chp", Type = "image", Offset = 0x11A9BF, UnpackedSize = 0x0AC436, Size = 0x297BB, IsPacked = true }, + new PackedEntry { Name = "b_cain_c.chp", Type = "image", Offset = 0x14417A, UnpackedSize = 0x9C436, Size = 0x2557D, IsPacked = true }, + new PackedEntry { Name = "b_chia_a.chp", Type = "image", Offset = 0x1696F7, UnpackedSize = 0x64436, Size = 0x185EA, IsPacked = true }, + new PackedEntry { Name = "b_chib_a.chp", Type = "image", Offset = 0x181CE1, UnpackedSize = 0x64436, Size = 0x189B8, IsPacked = true }, + new PackedEntry { Name = "b_chic_a.chp", Type = "image", Offset = 0x19A699, UnpackedSize = 0x2C436, Size = 0x0BFD9, IsPacked = true }, + new PackedEntry { Name = "b_clim_a.chp", Type = "image", Offset = 0x1A6672, UnpackedSize = 0x3C436, Size = 0x0F216, IsPacked = true }, + new PackedEntry { Name = "b_clim_b.chp", Type = "image", Offset = 0x1B5888, UnpackedSize = 0x44436, Size = 0x0F9E8, IsPacked = true }, + new PackedEntry { Name = "b_clim_c.chp", Type = "image", Offset = 0x1C5270, UnpackedSize = 0x34436, Size = 0x0BD94, IsPacked = true }, + new PackedEntry { Name = "b_cur1_a.chp", Type = "image", Offset = 0x1D1004, UnpackedSize = 0x14436, Size = 0x55D8, IsPacked = true }, + new PackedEntry { Name = "b_cur2_a.chp", Type = "image", Offset = 0x1D65DC, UnpackedSize = 0x68436, Size = 0x14FB9, IsPacked = true }, + new PackedEntry { Name = "b_dem1_a.chp", Type = "image", Offset = 0x1EB595, UnpackedSize = 0x54436, Size = 0x14028, IsPacked = true }, + new PackedEntry { Name = "b_dem1_b.chp", Type = "image", Offset = 0x1FF5BD, UnpackedSize = 0x54436, Size = 0x1378C, IsPacked = true }, + new PackedEntry { Name = "b_dog_b.chp", Type = "image", Offset = 0x212D49, UnpackedSize = 0x58436, Size = 0x15D6C, IsPacked = true }, + new PackedEntry { Name = "b_ga1a_b.chp", Type = "image", Offset = 0x228AB5, UnpackedSize = 0x2C436, Size = 0x0AF19, IsPacked = true }, + new PackedEntry { Name = "b_ga1b_b.chp", Type = "image", Offset = 0x2339CE, UnpackedSize = 0x68436, Size = 0x1625A, IsPacked = true }, + new PackedEntry { Name = "b_ga2a_a.chp", Type = "image", Offset = 0x249C28, UnpackedSize = 0x10436, Size = 0x340E, IsPacked = true }, + new PackedEntry { Name = "b_ga2b_a.chp", Type = "image", Offset = 0x24D036, UnpackedSize = 0x48436, Size = 0x0F5F0, IsPacked = true }, + new PackedEntry { Name = "b_hang_a.chp", Type = "image", Offset = 0x25C626, UnpackedSize = 0x78436, Size = 0x1B8CD, IsPacked = true }, + new PackedEntry { Name = "b_harp_a.chp", Type = "image", Offset = 0x277EF3, UnpackedSize = 0x5C436, Size = 0x1AF96, IsPacked = true }, + new PackedEntry { Name = "b_harp_b.chp", Type = "image", Offset = 0x292E89, UnpackedSize = 0x58436, Size = 0x1A35F, IsPacked = true }, + new PackedEntry { Name = "b_hebi_a.chp", Type = "image", Offset = 0x2AD1E8, UnpackedSize = 0x40436, Size = 0x114DB, IsPacked = true }, + new PackedEntry { Name = "b_hei1_a.chp", Type = "image", Offset = 0x2BE6C3, UnpackedSize = 0x5C436, Size = 0x15985, IsPacked = true }, + new PackedEntry { Name = "b_icon.chp", Type = "image", Offset = 0x2D4048, UnpackedSize = 0x20436, Size = 0x69B8, IsPacked = true }, + new PackedEntry { Name = "b_iconb.chp", Type = "image", Offset = 0x2DAA00, UnpackedSize = 0x8436, Size = 0x1247, IsPacked = true }, + new PackedEntry { Name = "b_jian_b.chp", Type = "image", Offset = 0x2DBC47, UnpackedSize = 0x98436, Size = 0x23179, IsPacked = true }, + new PackedEntry { Name = "b_kasi_a.chp", Type = "image", Offset = 0x2FEDC0, UnpackedSize = 0x6C436, Size = 0x1AFAF, IsPacked = true }, + new PackedEntry { Name = "b_kime_b.chp", Type = "image", Offset = 0x319D6F, UnpackedSize = 0x8C436, Size = 0x28E6F, IsPacked = true }, + new PackedEntry { Name = "b_kin1_a.chp", Type = "image", Offset = 0x342BDE, UnpackedSize = 0x64436, Size = 0x17298, IsPacked = true }, + new PackedEntry { Name = "b_kin2_a.chp", Type = "image", Offset = 0x359E76, UnpackedSize = 0x20436, Size = 0x6BE9, IsPacked = true }, + new PackedEntry { Name = "b_kin3_a.chp", Type = "image", Offset = 0x360A5F, UnpackedSize = 0x48436, Size = 0x0E5D6, IsPacked = true }, + new PackedEntry { Name = "b_kobo_a.chp", Type = "image", Offset = 0x36F035, UnpackedSize = 0x30436, Size = 0x0B881, IsPacked = true }, + new PackedEntry { Name = "b_kobo_b.chp", Type = "image", Offset = 0x37A8B6, UnpackedSize = 0x2C436, Size = 0x0A1FC, IsPacked = true }, + new PackedEntry { Name = "b_kobo_c.chp", Type = "image", Offset = 0x384AB2, UnpackedSize = 0x28436, Size = 0x8DEA, IsPacked = true }, + new PackedEntry { Name = "b_mac1_b.chp", Type = "image", Offset = 0x38D89C, UnpackedSize = 0x10436, Size = 0x3160, IsPacked = true }, + new PackedEntry { Name = "b_mac2_b.chp", Type = "image", Offset = 0x3909FC, UnpackedSize = 0x10436, Size = 0x30D4, IsPacked = true }, + new PackedEntry { Name = "b_mac3_b.chp", Type = "image", Offset = 0x393AD0, UnpackedSize = 0x50436, Size = 0x111D5, IsPacked = true }, + new PackedEntry { Name = "b_magic0.chp", Type = "image", Offset = 0x3A4CA5, UnpackedSize = 0x14436, Size = 0x3E5C, IsPacked = true }, + new PackedEntry { Name = "b_magic1.chp", Type = "image", Offset = 0x3A8B01, UnpackedSize = 0x14436, Size = 0x3A5F, IsPacked = true }, + new PackedEntry { Name = "b_magic2.chp", Type = "image", Offset = 0x3AC560, UnpackedSize = 0x4436, Size = 0x558, IsPacked = true }, + new PackedEntry { Name = "b_magic3.chp", Type = "image", Offset = 0x3ACAB8, UnpackedSize = 0x4436, Size = 0x3AF, IsPacked = true }, + new PackedEntry { Name = "b_magic4.chp", Type = "image", Offset = 0x3ACE67, UnpackedSize = 0x10436, Size = 0x3FB6, IsPacked = true }, + new PackedEntry { Name = "b_magic5.chp", Type = "image", Offset = 0x3B0E1D, UnpackedSize = 0x18436, Size = 0x5BE3, IsPacked = true }, + new PackedEntry { Name = "b_magic6.chp", Type = "image", Offset = 0x3B6A00, UnpackedSize = 0x18436, Size = 0x5D43, IsPacked = true }, + new PackedEntry { Name = "b_magic7.chp", Type = "image", Offset = 0x3BC743, UnpackedSize = 0x20436, Size = 0x5913, IsPacked = true }, + new PackedEntry { Name = "b_magic8.chp", Type = "image", Offset = 0x3C2056, UnpackedSize = 0x0C436, Size = 0x230C, IsPacked = true }, + new PackedEntry { Name = "b_maj1_a.chp", Type = "image", Offset = 0x3C4362, UnpackedSize = 0x30436, Size = 0x0B252, IsPacked = true }, + new PackedEntry { Name = "b_pon_a.chp", Type = "image", Offset = 0x3CF5B4, UnpackedSize = 0x70436, Size = 0x1D13E, IsPacked = true }, + new PackedEntry { Name = "b_pon_b.chp", Type = "image", Offset = 0x3EC6F2, UnpackedSize = 0x6C436, Size = 0x1C2BB, IsPacked = true }, + new PackedEntry { Name = "b_pon_c.chp", Type = "image", Offset = 0x4089AD, UnpackedSize = 0x74436, Size = 0x1C839, IsPacked = true }, + new PackedEntry { Name = "b_riq_a.chp", Type = "image", Offset = 0x4251E6, UnpackedSize = 0x5C436, Size = 0x18D82, IsPacked = true }, + new PackedEntry { Name = "b_riq_b.chp", Type = "image", Offset = 0x43DF68, UnpackedSize = 0x5C436, Size = 0x17535, IsPacked = true }, + new PackedEntry { Name = "b_riq_c.chp", Type = "image", Offset = 0x45549D, UnpackedSize = 0x58436, Size = 0x14B4C, IsPacked = true }, + new PackedEntry { Name = "b_rob1_a.chp", Type = "image", Offset = 0x469FE9, UnpackedSize = 0x48436, Size = 0x12554, IsPacked = true }, + new PackedEntry { Name = "b_russ_a.chp", Type = "image", Offset = 0x47C53D, UnpackedSize = 0x6C436, Size = 0x19E1F, IsPacked = true }, + new PackedEntry { Name = "b_russ_b.chp", Type = "image", Offset = 0x49635C, UnpackedSize = 0x6C436, Size = 0x1A2F6, IsPacked = true }, + new PackedEntry { Name = "b_russ_c.chp", Type = "image", Offset = 0x4B0652, UnpackedSize = 0x60436, Size = 0x178CE, IsPacked = true }, + new PackedEntry { Name = "b_sab1_a.chp", Type = "image", Offset = 0x4C7F20, UnpackedSize = 0x90436, Size = 0x23C3D, IsPacked = true }, + new PackedEntry { Name = "b_semu_b.chp", Type = "image", Offset = 0x4EBB5D, UnpackedSize = 0x74436, Size = 0x1A958, IsPacked = true }, + new PackedEntry { Name = "b_skal_a.chp", Type = "image", Offset = 0x5064B5, UnpackedSize = 0x5C436, Size = 0x1596C, IsPacked = true }, + new PackedEntry { Name = "b_skal_b.chp", Type = "image", Offset = 0x51BE21, UnpackedSize = 0x5C436, Size = 0x15C42, IsPacked = true }, + new PackedEntry { Name = "b_skal_c.chp", Type = "image", Offset = 0x531A63, UnpackedSize = 0x58436, Size = 0x147BA, IsPacked = true }, + new PackedEntry { Name = "b_sura_a.chp", Type = "image", Offset = 0x54621D, UnpackedSize = 0x28436, Size = 0x6655, IsPacked = true }, + new PackedEntry { Name = "b_sura_b.chp", Type = "image", Offset = 0x54C872, UnpackedSize = 0x24436, Size = 0x624F, IsPacked = true }, + new PackedEntry { Name = "b_sura_c.chp", Type = "image", Offset = 0x552AC1, UnpackedSize = 0x24436, Size = 0x5EDE, IsPacked = true }, + new PackedEntry { Name = "b_sys.chp", Type = "image", Offset = 0x55899F, UnpackedSize = 0x18436, Size = 0x34EC, IsPacked = true }, + new PackedEntry { Name = "b_sys2.chp", Type = "image", Offset = 0x55BE8B, UnpackedSize = 0x18436, Size = 0x3201, IsPacked = true }, + new PackedEntry { Name = "b_thi1_a.chp", Type = "image", Offset = 0x55F08C, UnpackedSize = 0x44436, Size = 0x11DFF, IsPacked = true }, + new PackedEntry { Name = "b_tira_a.chp", Type = "image", Offset = 0x570E8B, UnpackedSize = 0x70436, Size = 0x1A351, IsPacked = true }, + new PackedEntry { Name = "b_tora_a.chp", Type = "image", Offset = 0x58B1DC, UnpackedSize = 0x80436, Size = 0x24E08, IsPacked = true }, + new PackedEntry { Name = "b_tora_b.chp", Type = "image", Offset = 0x5AFFE4, UnpackedSize = 0x88436, Size = 0x25294, IsPacked = true }, + new PackedEntry { Name = "b_tora_c.chp", Type = "image", Offset = 0x5D5278, UnpackedSize = 0x7C436, Size = 0x20C2C, IsPacked = true }, + new PackedEntry { Name = "b_tree_a.chp", Type = "image", Offset = 0x5F5EA4, UnpackedSize = 0x5C436, Size = 0x13587, IsPacked = true }, + new PackedEntry { Name = "b_uma.chp", Type = "image", Offset = 0x60942B, UnpackedSize = 0x4436, Size = 0x10C, IsPacked = true }, + new PackedEntry { Name = "b_uma1_b.chp", Type = "image", Offset = 0x609537, UnpackedSize = 0x8C436, Size = 0x2193B, IsPacked = true }, + new PackedEntry { Name = "b_wasi_a.chp", Type = "image", Offset = 0x62AE72, UnpackedSize = 0x70436, Size = 0x1C948, IsPacked = true }, + new PackedEntry { Name = "b_wasi_b.chp", Type = "image", Offset = 0x6477BA, UnpackedSize = 0x70436, Size = 0x1C856, IsPacked = true }, + new PackedEntry { Name = "b_wiz1_a.chp", Type = "image", Offset = 0x664010, UnpackedSize = 0x64436, Size = 0x173C1, IsPacked = true }, + new PackedEntry { Name = "b_yaji_c.chp", Type = "image", Offset = 0x67B3D1, UnpackedSize = 0x80436, Size = 0x20154, IsPacked = true }, + new PackedEntry { Name = "b_zom1_b.chp", Type = "image", Offset = 0x69B525, UnpackedSize = 0x40436, Size = 0x0E7FA, IsPacked = true }, + new PackedEntry { Name = "con_chr.chp", Type = "image", Offset = 0x6A9D1F, UnpackedSize = 0x10436, Size = 0x12C4, IsPacked = true }, + new PackedEntry { Name = "f_abel.chp", Type = "image", Offset = 0x6AAFE3, UnpackedSize = 0x20436, Size = 0x6F04, IsPacked = true }, + new PackedEntry { Name = "f_annin.chp", Type = "image", Offset = 0x6B1EE7, UnpackedSize = 0x24436, Size = 0x911F, IsPacked = true }, + new PackedEntry { Name = "f_baba.chp", Type = "image", Offset = 0x6BB006, UnpackedSize = 0x10436, Size = 0x361A, IsPacked = true }, + new PackedEntry { Name = "f_bajil.chp", Type = "image", Offset = 0x6BE620, UnpackedSize = 0x14436, Size = 0x492E, IsPacked = true }, + new PackedEntry { Name = "f_baten.chp", Type = "image", Offset = 0x6C2F4E, UnpackedSize = 0x10436, Size = 0x331B, IsPacked = true }, + new PackedEntry { Name = "f_bobes.chp", Type = "image", Offset = 0x6C6269, UnpackedSize = 0x34436, Size = 0x0D637, IsPacked = true }, + new PackedEntry { Name = "f_bosco.chp", Type = "image", Offset = 0x6D38A0, UnpackedSize = 0x28436, Size = 0x0A5D0, IsPacked = true }, + new PackedEntry { Name = "f_boy1.chp", Type = "image", Offset = 0x6DDE70, UnpackedSize = 0x18436, Size = 0x54C6, IsPacked = true }, + new PackedEntry { Name = "f_buki.chp", Type = "image", Offset = 0x6E3336, UnpackedSize = 0x10436, Size = 0x4599, IsPacked = true }, + new PackedEntry { Name = "f_cain.chp", Type = "image", Offset = 0x6E78CF, UnpackedSize = 0x48436, Size = 0x1312E, IsPacked = true }, + new PackedEntry { Name = "f_chibi.chp", Type = "image", Offset = 0x6FA9FD, UnpackedSize = 0x10436, Size = 0x3346, IsPacked = true }, + new PackedEntry { Name = "f_clim1.chp", Type = "image", Offset = 0x6FDD43, UnpackedSize = 0x10436, Size = 0x372A, IsPacked = true }, + new PackedEntry { Name = "f_clim2.chp", Type = "image", Offset = 0x70146D, UnpackedSize = 0x18436, Size = 0x5C51, IsPacked = true }, + new PackedEntry { Name = "f_coin.chp", Type = "image", Offset = 0x7070BE, UnpackedSize = 0x10436, Size = 0x4830, IsPacked = true }, + new PackedEntry { Name = "f_cura.chp", Type = "image", Offset = 0x70B8EE, UnpackedSize = 0x14436, Size = 0x44C6, IsPacked = true }, + new PackedEntry { Name = "f_door1.chp", Type = "image", Offset = 0x70FDB4, UnpackedSize = 0x8436, Size = 0x0E4B, IsPacked = true }, + new PackedEntry { Name = "f_door10.chp", Type = "image", Offset = 0x710BFF, UnpackedSize = 0x8436, Size = 0x802, IsPacked = true }, + new PackedEntry { Name = "f_door11.chp", Type = "image", Offset = 0x711401, UnpackedSize = 0x0C436, Size = 0x0CBF, IsPacked = true }, + new PackedEntry { Name = "f_door12.chp", Type = "image", Offset = 0x7120C0, UnpackedSize = 0x0C436, Size = 0x2F24, IsPacked = true }, + new PackedEntry { Name = "f_door2.chp", Type = "image", Offset = 0x714FE4, UnpackedSize = 0x0C436, Size = 0x1633, IsPacked = true }, + new PackedEntry { Name = "f_door3.chp", Type = "image", Offset = 0x716617, UnpackedSize = 0x0C436, Size = 0x159C, IsPacked = true }, + new PackedEntry { Name = "f_door4.chp", Type = "image", Offset = 0x717BB3, UnpackedSize = 0x8436, Size = 0x0EA9, IsPacked = true }, + new PackedEntry { Name = "f_door5.chp", Type = "image", Offset = 0x718A5C, UnpackedSize = 0x8436, Size = 0x0C35, IsPacked = true }, + new PackedEntry { Name = "f_door6.chp", Type = "image", Offset = 0x719691, UnpackedSize = 0x8436, Size = 0x0D1A, IsPacked = true }, + new PackedEntry { Name = "f_door7.chp", Type = "image", Offset = 0x71A3AB, UnpackedSize = 0x4436, Size = 0x74C, IsPacked = true }, + new PackedEntry { Name = "f_door8.chp", Type = "image", Offset = 0x71AAF7, UnpackedSize = 0x8436, Size = 0x0AAF, IsPacked = true }, + new PackedEntry { Name = "f_door9.chp", Type = "image", Offset = 0x71B5A6, UnpackedSize = 0x0C436, Size = 0x0CC2, IsPacked = true }, + new PackedEntry { Name = "f_dummy.chp", Type = "image", Offset = 0x71C268, UnpackedSize = 0x4436, Size = 0x10C, IsPacked = true }, + new PackedEntry { Name = "f_funsui.chp", Type = "image", Offset = 0x71C374, UnpackedSize = 0x20436, Size = 0x74D2, IsPacked = true }, + new PackedEntry { Name = "f_futa.chp", Type = "image", Offset = 0x723846, UnpackedSize = 0x4436, Size = 0x0A73, IsPacked = true }, + new PackedEntry { Name = "f_gaki.chp", Type = "image", Offset = 0x7242B9, UnpackedSize = 0x0C436, Size = 0x2564, IsPacked = true }, + new PackedEntry { Name = "f_gal1.chp", Type = "image", Offset = 0x72681D, UnpackedSize = 0x18436, Size = 0x5128, IsPacked = true }, + new PackedEntry { Name = "f_gal2.chp", Type = "image", Offset = 0x72B945, UnpackedSize = 0x18436, Size = 0x5160, IsPacked = true }, + new PackedEntry { Name = "f_gana.chp", Type = "image", Offset = 0x730AA5, UnpackedSize = 0x14436, Size = 0x4C76, IsPacked = true }, + new PackedEntry { Name = "f_hasi.chp", Type = "image", Offset = 0x73571B, UnpackedSize = 0x4436, Size = 0x646, IsPacked = true }, + new PackedEntry { Name = "f_hei.chp", Type = "image", Offset = 0x735D61, UnpackedSize = 0x28436, Size = 0x8F85, IsPacked = true }, + new PackedEntry { Name = "f_icon.chp", Type = "image", Offset = 0x73ECE6, UnpackedSize = 0x24436, Size = 0x962B, IsPacked = true }, + new PackedEntry { Name = "f_iconb.chp", Type = "image", Offset = 0x748311, UnpackedSize = 0x14436, Size = 0x31C5, IsPacked = true }, + new PackedEntry { Name = "f_jiji1.chp", Type = "image", Offset = 0x74B4D6, UnpackedSize = 0x18436, Size = 0x448C, IsPacked = true }, + new PackedEntry { Name = "f_jiji2.chp", Type = "image", Offset = 0x74F962, UnpackedSize = 0x18436, Size = 0x4C6D, IsPacked = true }, + new PackedEntry { Name = "f_kasira.chp", Type = "image", Offset = 0x7545CF, UnpackedSize = 0x1C436, Size = 0x4276, IsPacked = true }, + new PackedEntry { Name = "f_king.chp", Type = "image", Offset = 0x758845, UnpackedSize = 0x18436, Size = 0x630B, IsPacked = true }, + new PackedEntry { Name = "f_kuro1.chp", Type = "image", Offset = 0x75EB50, UnpackedSize = 0x10436, Size = 0x2F64, IsPacked = true }, + new PackedEntry { Name = "f_kuro2.chp", Type = "image", Offset = 0x761AB4, UnpackedSize = 0x8436, Size = 0x158A, IsPacked = true }, + new PackedEntry { Name = "f_kuro3.chp", Type = "image", Offset = 0x76303E, UnpackedSize = 0x8436, Size = 0x1557, IsPacked = true }, + new PackedEntry { Name = "f_mado.chp", Type = "image", Offset = 0x764595, UnpackedSize = 0x1C436, Size = 0x62E6, IsPacked = true }, + new PackedEntry { Name = "f_mafin1.chp", Type = "image", Offset = 0x76A87B, UnpackedSize = 0x8436, Size = 0x1695, IsPacked = true }, + new PackedEntry { Name = "f_mafin2.chp", Type = "image", Offset = 0x76BF10, UnpackedSize = 0x10436, Size = 0x3AA7, IsPacked = true }, + new PackedEntry { Name = "f_mafin3.chp", Type = "image", Offset = 0x76F9B7, UnpackedSize = 0x8436, Size = 0x1A9E, IsPacked = true }, + new PackedEntry { Name = "f_mafin4.chp", Type = "image", Offset = 0x771455, UnpackedSize = 0x1C436, Size = 0x56DE, IsPacked = true }, + new PackedEntry { Name = "f_mam.chp", Type = "image", Offset = 0x776B33, UnpackedSize = 0x18436, Size = 0x4C4B, IsPacked = true }, + new PackedEntry { Name = "f_maypl.chp", Type = "image", Offset = 0x77B77E, UnpackedSize = 0x0C436, Size = 0x2E89, IsPacked = true }, + new PackedEntry { Name = "f_meido.chp", Type = "image", Offset = 0x77E607, UnpackedSize = 0x18436, Size = 0x4C5E, IsPacked = true }, + new PackedEntry { Name = "f_milf1.chp", Type = "image", Offset = 0x783265, UnpackedSize = 0x2C436, Size = 0x9B21, IsPacked = true }, + new PackedEntry { Name = "f_milf2.chp", Type = "image", Offset = 0x78CD86, UnpackedSize = 0x20436, Size = 0x7AB0, IsPacked = true }, + new PackedEntry { Name = "f_milf3.chp", Type = "image", Offset = 0x794836, UnpackedSize = 0x8436, Size = 0x1D55, IsPacked = true }, + new PackedEntry { Name = "f_mitugo.chp", Type = "image", Offset = 0x79658B, UnpackedSize = 0x10436, Size = 0x2D45, IsPacked = true }, + new PackedEntry { Name = "f_oba.chp", Type = "image", Offset = 0x7992D0, UnpackedSize = 0x18436, Size = 0x4FFE, IsPacked = true }, + new PackedEntry { Name = "f_panna.chp", Type = "image", Offset = 0x79E2CE, UnpackedSize = 0x14436, Size = 0x4E5F, IsPacked = true }, + new PackedEntry { Name = "f_ponti.chp", Type = "image", Offset = 0x7A312D, UnpackedSize = 0x24436, Size = 0x8D7F, IsPacked = true }, + new PackedEntry { Name = "f_queen.chp", Type = "image", Offset = 0x7ABEAC, UnpackedSize = 0x14436, Size = 0x58C3, IsPacked = true }, + new PackedEntry { Name = "f_riqur1.chp", Type = "image", Offset = 0x7B176F, UnpackedSize = 0x1C436, Size = 0x688D, IsPacked = true }, + new PackedEntry { Name = "f_riqur2.chp", Type = "image", Offset = 0x7B7FFC, UnpackedSize = 0x8436, Size = 0x1ABC, IsPacked = true }, + new PackedEntry { Name = "f_russ1.chp", Type = "image", Offset = 0x7B9AB8, UnpackedSize = 0x20436, Size = 0x6C37, IsPacked = true }, + new PackedEntry { Name = "f_russ2.chp", Type = "image", Offset = 0x7C06EF, UnpackedSize = 0x14436, Size = 0x500B, IsPacked = true }, + new PackedEntry { Name = "f_sable.chp", Type = "image", Offset = 0x7C56FA, UnpackedSize = 0x18436, Size = 0x59B6, IsPacked = true }, + new PackedEntry { Name = "f_sable2.chp", Type = "image", Offset = 0x7CB0B0, UnpackedSize = 0x30436, Size = 0x948E, IsPacked = true }, + new PackedEntry { Name = "f_selis.chp", Type = "image", Offset = 0x7D453E, UnpackedSize = 0x14436, Size = 0x50EB, IsPacked = true }, + new PackedEntry { Name = "f_selis1.chp", Type = "image", Offset = 0x7D9629, UnpackedSize = 0x0C436, Size = 0x2C74, IsPacked = true }, + new PackedEntry { Name = "f_selis2.chp", Type = "image", Offset = 0x7DC29D, UnpackedSize = 0x1C436, Size = 0x7405, IsPacked = true }, + new PackedEntry { Name = "f_selis3.chp", Type = "image", Offset = 0x7E36A2, UnpackedSize = 0x10436, Size = 0x3F4E, IsPacked = true }, + new PackedEntry { Name = "f_shake.chp", Type = "image", Offset = 0x7E75F0, UnpackedSize = 0x18436, Size = 0x6E76, IsPacked = true }, + new PackedEntry { Name = "f_shop1.chp", Type = "image", Offset = 0x7EE466, UnpackedSize = 0x1C436, Size = 0x5BEE, IsPacked = true }, + new PackedEntry { Name = "f_shop3.chp", Type = "image", Offset = 0x7F4054, UnpackedSize = 0x1C436, Size = 0x5978, IsPacked = true }, + new PackedEntry { Name = "f_sipul1.chp", Type = "image", Offset = 0x7F99CC, UnpackedSize = 0x10436, Size = 0x32F1, IsPacked = true }, + new PackedEntry { Name = "f_sipul2.chp", Type = "image", Offset = 0x7FCCBD, UnpackedSize = 0x8436, Size = 0x16C7, IsPacked = true }, + new PackedEntry { Name = "f_sipul3.chp", Type = "image", Offset = 0x7FE384, UnpackedSize = 0x2C436, Size = 0x9F3A, IsPacked = true }, + new PackedEntry { Name = "f_syoko.chp", Type = "image", Offset = 0x8082BE, UnpackedSize = 0x10436, Size = 0x4199, IsPacked = true }, + new PackedEntry { Name = "f_syoko2.chp", Type = "image", Offset = 0x80C457, UnpackedSize = 0x28436, Size = 0x6CD1, IsPacked = true }, + new PackedEntry { Name = "f_sys.chp", Type = "image", Offset = 0x813128, UnpackedSize = 0x8436, Size = 0x0A01, IsPacked = true }, + new PackedEntry { Name = "f_sys2.chp", Type = "image", Offset = 0x813B29, UnpackedSize = 0x8436, Size = 0x72C, IsPacked = true }, + new PackedEntry { Name = "f_syuku.chp", Type = "image", Offset = 0x814255, UnpackedSize = 0x10436, Size = 0x3520, IsPacked = true }, + new PackedEntry { Name = "f_taka.chp", Type = "image", Offset = 0x817775, UnpackedSize = 0x4436, Size = 0x0B3D, IsPacked = true }, + new PackedEntry { Name = "f_tira.chp", Type = "image", Offset = 0x8182B2, UnpackedSize = 0x10436, Size = 0x247E, IsPacked = true }, + new PackedEntry { Name = "f_tolte.chp", Type = "image", Offset = 0x81A730, UnpackedSize = 0x20436, Size = 0x6E12, IsPacked = true }, + new PackedEntry { Name = "f_tolte1.chp", Type = "image", Offset = 0x821542, UnpackedSize = 0x4436, Size = 0x10C, IsPacked = true }, + new PackedEntry { Name = "f_tryu.chp", Type = "image", Offset = 0x82164E, UnpackedSize = 0x18436, Size = 0x49BC, IsPacked = true }, + new PackedEntry { Name = "f_uma.chp", Type = "image", Offset = 0x82600A, UnpackedSize = 0x2C436, Size = 0x8DD6, IsPacked = true }, + new PackedEntry { Name = "f_zaha.chp", Type = "image", Offset = 0x82EDE0, UnpackedSize = 0x18436, Size = 0x54D1, IsPacked = true }, + new PackedEntry { Name = "g_cain.chp", Type = "image", Offset = 0x8342B1, UnpackedSize = 0x20436, Size = 0x8E99, IsPacked = true }, + new PackedEntry { Name = "ha.chp", Type = "image", Offset = 0x83D14A, UnpackedSize = 0x14436, Size = 0x2CC6, IsPacked = true }, + new PackedEntry { Name = "kidan_a.chp", Type = "image", Offset = 0x83FE10, UnpackedSize = 0x1C436, Size = 0x5019, IsPacked = true }, + new PackedEntry { Name = "kidan_b.chp", Type = "image", Offset = 0x844E29, UnpackedSize = 0x14436, Size = 0x35A3, IsPacked = true }, + new PackedEntry { Name = "kidan_c.chp", Type = "image", Offset = 0x8483CC, UnpackedSize = 0x1C436, Size = 0x4FA3, IsPacked = true }, + new PackedEntry { Name = "kin2_a.chp", Type = "image", Offset = 0x84D36F, UnpackedSize = 0x4436, Size = 0x10C, IsPacked = true }, + new PackedEntry { Name = "obj.chp", Type = "image", Offset = 0x84D47B, UnpackedSize = 0x4436, Size = 0x3AF, IsPacked = true }, + new PackedEntry { Name = "start.chp", Type = "image", Offset = 0x84D82A, UnpackedSize = 0x0C436, Size = 0x21D1, IsPacked = true }, + new PackedEntry { Name = "s_cain.chp", Type = "image", Offset = 0x84F9FB, UnpackedSize = 0x14436, Size = 0x3716, IsPacked = true }, + new PackedEntry { Name = "winc.chp", Type = "image", Offset = 0x853111, UnpackedSize = 0x4436, Size = 0x867, IsPacked = true }, + new PackedEntry { Name = "winc2.chp", Type = "image", Offset = 0x853978, UnpackedSize = 0x4436, Size = 0x85E, IsPacked = true }, + new PackedEntry { Name = "winct.chp", Type = "image", Offset = 0x8541D6, UnpackedSize = 0x4436, Size = 0x85C, IsPacked = true }, + new PackedEntry { Name = "x_sys.chp", Type = "image", Offset = 0x854A32, UnpackedSize = 0x4436, Size = 0x115, IsPacked = true }, + } + }, + { + "ALLGRP.273", new List() { + new PackedEntry { Name = "Bgm.gem", Type = "image", Offset = 0x0, UnpackedSize = 0x3EC36, Size = 0x19A9F, IsPacked = true }, + new PackedEntry { Name = "Black.gps", Type = "image", Offset = 0x19A9F, UnpackedSize = 0x3EC36, Size = 0x0BEF, IsPacked = true }, + new PackedEntry { Name = "Cgm_anni.gem", Type = "image", Offset = 0x1A68E, UnpackedSize = 0x3EC36, Size = 0x25D4, IsPacked = true }, + new PackedEntry { Name = "Cgm_bg.gps", Type = "image", Offset = 0x1CC62, UnpackedSize = 0x3EC36, Size = 0x0E53E, IsPacked = true }, + new PackedEntry { Name = "Cgm_crim.gem", Type = "image", Offset = 0x2B1A0, UnpackedSize = 0x3EC36, Size = 0x24D5, IsPacked = true }, + new PackedEntry { Name = "Cgm_gana.gem", Type = "image", Offset = 0x2D675, UnpackedSize = 0x3EC36, Size = 0x2859, IsPacked = true }, + new PackedEntry { Name = "Cgm_king.gem", Type = "image", Offset = 0x2FECE, UnpackedSize = 0x3EC36, Size = 0x17D1, IsPacked = true }, + new PackedEntry { Name = "Cgm_mafi.gem", Type = "image", Offset = 0x3169F, UnpackedSize = 0x3EC36, Size = 0x2CEA, IsPacked = true }, + new PackedEntry { Name = "Cgm_milf.gem", Type = "image", Offset = 0x34389, UnpackedSize = 0x3EC36, Size = 0x3054, IsPacked = true }, + new PackedEntry { Name = "Cgm_pann.gem", Type = "image", Offset = 0x373DD, UnpackedSize = 0x3EC36, Size = 0x286E, IsPacked = true }, + new PackedEntry { Name = "Cgm_quee.gem", Type = "image", Offset = 0x39C4B, UnpackedSize = 0x3EC36, Size = 0x2FDC, IsPacked = true }, + new PackedEntry { Name = "Cgm_riqu.gem", Type = "image", Offset = 0x3CC27, UnpackedSize = 0x3EC36, Size = 0x2974, IsPacked = true }, + new PackedEntry { Name = "Cgm_ruse.gem", Type = "image", Offset = 0x3F59B, UnpackedSize = 0x3EC36, Size = 0x2AE2, IsPacked = true }, + new PackedEntry { Name = "Cgm_seli.gem", Type = "image", Offset = 0x4207D, UnpackedSize = 0x3EC36, Size = 0x2A67, IsPacked = true }, + new PackedEntry { Name = "Cgm_shak.gem", Type = "image", Offset = 0x44AE4, UnpackedSize = 0x3EC36, Size = 0x2947, IsPacked = true }, + new PackedEntry { Name = "Cgm_shok.gem", Type = "image", Offset = 0x4742B, UnpackedSize = 0x3EC36, Size = 0x2943, IsPacked = true }, + new PackedEntry { Name = "Cgm_shuk.gem", Type = "image", Offset = 0x49D6E, UnpackedSize = 0x3EC36, Size = 0x254A, IsPacked = true }, + new PackedEntry { Name = "Cgm_tira.gem", Type = "image", Offset = 0x4C2B8, UnpackedSize = 0x3EC36, Size = 0x2873, IsPacked = true }, + new PackedEntry { Name = "Cgm_tolt.gem", Type = "image", Offset = 0x4EB2B, UnpackedSize = 0x3EC36, Size = 0x26B6, IsPacked = true }, + new PackedEntry { Name = "Clr_bg.gps", Type = "image", Offset = 0x511E1, UnpackedSize = 0x3EC36, Size = 0x0CD03, IsPacked = true }, + new PackedEntry { Name = "Config.gps", Type = "image", Offset = 0x5DEE4, UnpackedSize = 0x3EC36, Size = 0x3D93, IsPacked = true }, + new PackedEntry { Name = "Equ.gem", Type = "image", Offset = 0x61C77, UnpackedSize = 0x3EC36, Size = 0x3214, IsPacked = true }, + new PackedEntry { Name = "Fol.gps", Type = "image", Offset = 0x64E8B, UnpackedSize = 0x3EC36, Size = 0x870E, IsPacked = true }, + new PackedEntry { Name = "Fon.gps", Type = "image", Offset = 0x6D599, UnpackedSize = 0x3EC36, Size = 0x6445, IsPacked = true }, + new PackedEntry { Name = "Giga_ff.gem", Type = "image", Offset = 0x739DE, UnpackedSize = 0x3EC36, Size = 0x1447, IsPacked = true }, + new PackedEntry { Name = "G_over.gps", Type = "image", Offset = 0x74E25, UnpackedSize = 0x3EC36, Size = 0x0F997, IsPacked = true }, + new PackedEntry { Name = "Hb02_5b.gps", Type = "image", Offset = 0x847BC, UnpackedSize = 0x3EC36, Size = 0x167E8, IsPacked = true }, + new PackedEntry { Name = "Hb03_01.gem", Type = "image", Offset = 0x9AFA4, UnpackedSize = 0x3EC36, Size = 0x179F0, IsPacked = true }, + new PackedEntry { Name = "Hb03_02a.gps", Type = "image", Offset = 0x0B2994, UnpackedSize = 0x27036, Size = 0x9FBE, IsPacked = true }, + new PackedEntry { Name = "Hb03_02b.gem", Type = "image", Offset = 0x0BC952, UnpackedSize = 0x28436, Size = 0x3536, IsPacked = true }, + new PackedEntry { Name = "Hb03_03.gem", Type = "image", Offset = 0x0BFE88, UnpackedSize = 0x3EC36, Size = 0x2E6A8, IsPacked = true }, + new PackedEntry { Name = "Hb03_04.gem", Type = "image", Offset = 0x0EE530, UnpackedSize = 0x3EC36, Size = 0x35499, IsPacked = true }, + new PackedEntry { Name = "Hb03_05.gem", Type = "image", Offset = 0x1239C9, UnpackedSize = 0x3EC36, Size = 0x225E8, IsPacked = true }, + new PackedEntry { Name = "Hb03_06.gps", Type = "image", Offset = 0x145FB1, UnpackedSize = 0x3EC36, Size = 0x28BBF, IsPacked = true }, + new PackedEntry { Name = "Hb03_07.gps", Type = "image", Offset = 0x16EB70, UnpackedSize = 0x3EC36, Size = 0x264BB, IsPacked = true }, + new PackedEntry { Name = "Hb03_08a.gps", Type = "image", Offset = 0x19502B, UnpackedSize = 0x3EC36, Size = 0x194EE, IsPacked = true }, + new PackedEntry { Name = "Hb03_08b.gem", Type = "image", Offset = 0x1AE519, UnpackedSize = 0x3EC36, Size = 0x84B3, IsPacked = true }, + new PackedEntry { Name = "Hb03_08c.gem", Type = "image", Offset = 0x1B69CC, UnpackedSize = 0x3EC36, Size = 0x243F, IsPacked = true }, + new PackedEntry { Name = "Hb03_08d.gem", Type = "image", Offset = 0x1B8E0B, UnpackedSize = 0x3EC36, Size = 0x1B7B, IsPacked = true }, + new PackedEntry { Name = "Hb03_09.gps", Type = "image", Offset = 0x1BA986, UnpackedSize = 0x3EC36, Size = 0x16640, IsPacked = true }, + new PackedEntry { Name = "Hb03_10.gps", Type = "image", Offset = 0x1D0FC6, UnpackedSize = 0x3EC36, Size = 0x223F0, IsPacked = true }, + new PackedEntry { Name = "Hb03_e01.gps", Type = "image", Offset = 0x1F33B6, UnpackedSize = 0x3EC36, Size = 0x28491, IsPacked = true }, + new PackedEntry { Name = "Hb03_e02.gps", Type = "image", Offset = 0x21B847, UnpackedSize = 0x3EC36, Size = 0x2533D, IsPacked = true }, + new PackedEntry { Name = "Hb06_01.gem", Type = "image", Offset = 0x240B84, UnpackedSize = 0x3EC36, Size = 0x14617, IsPacked = true }, + new PackedEntry { Name = "Hb06_02.gem", Type = "image", Offset = 0x25519B, UnpackedSize = 0x3EC36, Size = 0x1474A, IsPacked = true }, + new PackedEntry { Name = "Hb06_03.gps", Type = "image", Offset = 0x2698E5, UnpackedSize = 0x28436, Size = 0x19A56, IsPacked = true }, + new PackedEntry { Name = "Hb06_04a.gps", Type = "image", Offset = 0x28333B, UnpackedSize = 0x3EC36, Size = 0x18B90, IsPacked = true }, + new PackedEntry { Name = "Hb06_04b.gem", Type = "image", Offset = 0x29BECB, UnpackedSize = 0x3EC36, Size = 0x16A7E, IsPacked = true }, + new PackedEntry { Name = "Hb06_05.gps", Type = "image", Offset = 0x2B2949, UnpackedSize = 0x3EC36, Size = 0x2506D, IsPacked = true }, + new PackedEntry { Name = "Hb06_06.gps", Type = "image", Offset = 0x2D79B6, UnpackedSize = 0x3EC36, Size = 0x14756, IsPacked = true }, + new PackedEntry { Name = "Hb06_07.gps", Type = "image", Offset = 0x2EC10C, UnpackedSize = 0x3EC36, Size = 0x2168A, IsPacked = true }, + new PackedEntry { Name = "Hb06_08a.gps", Type = "image", Offset = 0x30D796, UnpackedSize = 0x3EC36, Size = 0x1CE0D, IsPacked = true }, + new PackedEntry { Name = "Hb06_08b.gem", Type = "image", Offset = 0x32A5A3, UnpackedSize = 0x3EC36, Size = 0x25AF, IsPacked = true }, + new PackedEntry { Name = "Hb06_e01.gps", Type = "image", Offset = 0x32CB52, UnpackedSize = 0x3EC36, Size = 0x1CCCC, IsPacked = true }, + new PackedEntry { Name = "Hb06_e02.gps", Type = "image", Offset = 0x34981E, UnpackedSize = 0x3EC36, Size = 0x210A1, IsPacked = true }, + new PackedEntry { Name = "Hb07_01.gps", Type = "image", Offset = 0x36A8BF, UnpackedSize = 0x28436, Size = 0x123D6, IsPacked = true }, + new PackedEntry { Name = "Hb07_02.gps", Type = "image", Offset = 0x37CC95, UnpackedSize = 0x28436, Size = 0x135C7, IsPacked = true }, + new PackedEntry { Name = "Hb07_03.gps", Type = "image", Offset = 0x39025C, UnpackedSize = 0x28436, Size = 0x1A933, IsPacked = true }, + new PackedEntry { Name = "Hb07_04.gps", Type = "image", Offset = 0x3AAB8F, UnpackedSize = 0x28436, Size = 0x1C620, IsPacked = true }, + new PackedEntry { Name = "Hb07_05.gps", Type = "image", Offset = 0x3C71AF, UnpackedSize = 0x28436, Size = 0x14D8C, IsPacked = true }, + new PackedEntry { Name = "Hb07_06a.gps", Type = "image", Offset = 0x3DBF3B, UnpackedSize = 0x3EC36, Size = 0x19715, IsPacked = true }, + new PackedEntry { Name = "Hb07_06b.gem", Type = "image", Offset = 0x3F5650, UnpackedSize = 0x3EC36, Size = 0x0A56E, IsPacked = true }, + new PackedEntry { Name = "Hb07_07.gps", Type = "image", Offset = 0x3FFBBE, UnpackedSize = 0x3EC36, Size = 0x16B47, IsPacked = true }, + new PackedEntry { Name = "Hb07_08.gps", Type = "image", Offset = 0x416705, UnpackedSize = 0x3EC36, Size = 0x17E53, IsPacked = true }, + new PackedEntry { Name = "Hb07_08a.gps", Type = "image", Offset = 0x42E558, UnpackedSize = 0x3EC36, Size = 0x17894, IsPacked = true }, + new PackedEntry { Name = "Hb07_08b.gem", Type = "image", Offset = 0x445DEC, UnpackedSize = 0x3EC36, Size = 0x2581, IsPacked = true }, + new PackedEntry { Name = "Hb07_e01.gps", Type = "image", Offset = 0x44836D, UnpackedSize = 0x3EC36, Size = 0x27388, IsPacked = true }, + new PackedEntry { Name = "Hb07_e02.gps", Type = "image", Offset = 0x46F6F5, UnpackedSize = 0x3EC36, Size = 0x216FD, IsPacked = true }, + new PackedEntry { Name = "Hb11_01.gps", Type = "image", Offset = 0x490DF2, UnpackedSize = 0x28436, Size = 0x189BD, IsPacked = true }, + new PackedEntry { Name = "Hb11_02a.gps", Type = "image", Offset = 0x4A97AF, UnpackedSize = 0x28436, Size = 0x10592, IsPacked = true }, + new PackedEntry { Name = "Hb11_02b.gem", Type = "image", Offset = 0x4B9D41, UnpackedSize = 0x28436, Size = 0x2356, IsPacked = true }, + new PackedEntry { Name = "Hb11_03.gem", Type = "image", Offset = 0x4BC097, UnpackedSize = 0x3EC36, Size = 0x1AB65, IsPacked = true }, + new PackedEntry { Name = "Hb11_04.gps", Type = "image", Offset = 0x4D6BFC, UnpackedSize = 0x28436, Size = 0x1C34B, IsPacked = true }, + new PackedEntry { Name = "Hb11_05a.gps", Type = "image", Offset = 0x4F2F47, UnpackedSize = 0x3EC36, Size = 0x1B837, IsPacked = true }, + new PackedEntry { Name = "Hb11_05b.gem", Type = "image", Offset = 0x50E77E, UnpackedSize = 0x3EC36, Size = 0x5940, IsPacked = true }, + new PackedEntry { Name = "Hb11_05c.gem", Type = "image", Offset = 0x5140BE, UnpackedSize = 0x3EC36, Size = 0x0A85B, IsPacked = true }, + new PackedEntry { Name = "Hb11_05d.gem", Type = "image", Offset = 0x51E919, UnpackedSize = 0x3EC36, Size = 0x9848, IsPacked = true }, + new PackedEntry { Name = "Hb11_06.gps", Type = "image", Offset = 0x528161, UnpackedSize = 0x3EC36, Size = 0x1A922, IsPacked = true }, + new PackedEntry { Name = "Hb11_07.gps", Type = "image", Offset = 0x542A83, UnpackedSize = 0x3EC36, Size = 0x194FE, IsPacked = true }, + new PackedEntry { Name = "Hb11_08a.gps", Type = "image", Offset = 0x55BF81, UnpackedSize = 0x3EC36, Size = 0x1B41D, IsPacked = true }, + new PackedEntry { Name = "Hb11_08b.gem", Type = "image", Offset = 0x57739E, UnpackedSize = 0x3EC36, Size = 0x2CC6, IsPacked = true }, + new PackedEntry { Name = "Hb11_e01.gps", Type = "image", Offset = 0x57A064, UnpackedSize = 0x3EC36, Size = 0x20D2D, IsPacked = true }, + new PackedEntry { Name = "Hb11_e02.gps", Type = "image", Offset = 0x59AD91, UnpackedSize = 0x3EC36, Size = 0x1A64A, IsPacked = true }, + new PackedEntry { Name = "Hb12_01.gem", Type = "image", Offset = 0x5B53DB, UnpackedSize = 0x3EC36, Size = 0x16C61, IsPacked = true }, + new PackedEntry { Name = "Hb12_02.gps", Type = "image", Offset = 0x5CC03C, UnpackedSize = 0x28436, Size = 0x1A315, IsPacked = true }, + new PackedEntry { Name = "Hb12_03.gps", Type = "image", Offset = 0x5E6351, UnpackedSize = 0x28436, Size = 0x14ADB, IsPacked = true }, + new PackedEntry { Name = "Hb12_04.gps", Type = "image", Offset = 0x5FAE2C, UnpackedSize = 0x28436, Size = 0x0FC3C, IsPacked = true }, + new PackedEntry { Name = "Hb12_05a.gps", Type = "image", Offset = 0x60AA68, UnpackedSize = 0x3EC36, Size = 0x17FE8, IsPacked = true }, + new PackedEntry { Name = "Hb12_05b.gem", Type = "image", Offset = 0x622A50, UnpackedSize = 0x3EC36, Size = 0x6BE9, IsPacked = true }, + new PackedEntry { Name = "Hb12_05c.gem", Type = "image", Offset = 0x629639, UnpackedSize = 0x3EC36, Size = 0x4C40, IsPacked = true }, + new PackedEntry { Name = "Hb12_05d.gem", Type = "image", Offset = 0x62E279, UnpackedSize = 0x3EC36, Size = 0x4022, IsPacked = true }, + new PackedEntry { Name = "Hb12_06.gps", Type = "image", Offset = 0x63229B, UnpackedSize = 0x3EC36, Size = 0x17E19, IsPacked = true }, + new PackedEntry { Name = "Hb12_07.gps", Type = "image", Offset = 0x64A0B4, UnpackedSize = 0x3EC36, Size = 0x22683, IsPacked = true }, + new PackedEntry { Name = "Hb12_08a.gps", Type = "image", Offset = 0x66C737, UnpackedSize = 0x3EC36, Size = 0x16963, IsPacked = true }, + new PackedEntry { Name = "Hb12_08b.gem", Type = "image", Offset = 0x68309A, UnpackedSize = 0x3EC36, Size = 0x2DDE, IsPacked = true }, + new PackedEntry { Name = "Hb12_e01.gps", Type = "image", Offset = 0x685E78, UnpackedSize = 0x3EC36, Size = 0x22D4F, IsPacked = true }, + new PackedEntry { Name = "Hb12_e02.gps", Type = "image", Offset = 0x6A8BC7, UnpackedSize = 0x3EC36, Size = 0x1C1C9, IsPacked = true }, + new PackedEntry { Name = "Hb13_01.gem", Type = "image", Offset = 0x6C4D90, UnpackedSize = 0x3EC36, Size = 0x195E7, IsPacked = true }, + new PackedEntry { Name = "Hb13_02.gps", Type = "image", Offset = 0x6DE377, UnpackedSize = 0x28436, Size = 0x15C11, IsPacked = true }, + new PackedEntry { Name = "Hb13_03.gps", Type = "image", Offset = 0x6F3F88, UnpackedSize = 0x28436, Size = 0x18F28, IsPacked = true }, + new PackedEntry { Name = "Hb13_04.gem", Type = "image", Offset = 0x70CEB0, UnpackedSize = 0x3EC36, Size = 0x17D9D, IsPacked = true }, + new PackedEntry { Name = "Hb13_05.gps", Type = "image", Offset = 0x724C4D, UnpackedSize = 0x28436, Size = 0x17931, IsPacked = true }, + new PackedEntry { Name = "Hb13_06a.gps", Type = "image", Offset = 0x73C57E, UnpackedSize = 0x3EC36, Size = 0x20A47, IsPacked = true }, + new PackedEntry { Name = "Hb13_06b.gem", Type = "image", Offset = 0x75CFC5, UnpackedSize = 0x3EC36, Size = 0x0B1C1, IsPacked = true }, + new PackedEntry { Name = "Hb13_06c.gem", Type = "image", Offset = 0x768186, UnpackedSize = 0x3EC36, Size = 0x0B256, IsPacked = true }, + new PackedEntry { Name = "Hb13_06d.gem", Type = "image", Offset = 0x7733DC, UnpackedSize = 0x3EC36, Size = 0x1E8A, IsPacked = true }, + new PackedEntry { Name = "Hb13_07.gps", Type = "image", Offset = 0x775266, UnpackedSize = 0x3EC36, Size = 0x178B6, IsPacked = true }, + new PackedEntry { Name = "Hb13_08a.gps", Type = "image", Offset = 0x78CB1C, UnpackedSize = 0x3EC36, Size = 0x1276D, IsPacked = true }, + new PackedEntry { Name = "Hb13_08b.gem", Type = "image", Offset = 0x79F289, UnpackedSize = 0x3EC36, Size = 0x37AA, IsPacked = true }, + new PackedEntry { Name = "Hb13_e01.gps", Type = "image", Offset = 0x7A2A33, UnpackedSize = 0x3EC36, Size = 0x22397, IsPacked = true }, + new PackedEntry { Name = "Hb13_e02.gps", Type = "image", Offset = 0x7C4DCA, UnpackedSize = 0x3EC36, Size = 0x1F07F, IsPacked = true }, + new PackedEntry { Name = "Hb14_01.gps", Type = "image", Offset = 0x7E3E49, UnpackedSize = 0x28436, Size = 0x1B66E, IsPacked = true }, + new PackedEntry { Name = "Hb14_02a.gps", Type = "image", Offset = 0x7FF4B7, UnpackedSize = 0x28436, Size = 0x18825, IsPacked = true }, + new PackedEntry { Name = "Hb14_02b.gem", Type = "image", Offset = 0x817CDC, UnpackedSize = 0x28436, Size = 0x3028, IsPacked = true }, + new PackedEntry { Name = "Hb14_03.gps", Type = "image", Offset = 0x81AD04, UnpackedSize = 0x28436, Size = 0x0F841, IsPacked = true }, + new PackedEntry { Name = "Hb14_04a.gps", Type = "image", Offset = 0x82A545, UnpackedSize = 0x28436, Size = 0x12E49, IsPacked = true }, + new PackedEntry { Name = "Hb14_04b.gem", Type = "image", Offset = 0x83D38E, UnpackedSize = 0x28436, Size = 0x2C51, IsPacked = true }, + new PackedEntry { Name = "Hb14_05.gps", Type = "image", Offset = 0x83FFDF, UnpackedSize = 0x28436, Size = 0x19464, IsPacked = true }, + new PackedEntry { Name = "Hb14_06a.gps", Type = "image", Offset = 0x859443, UnpackedSize = 0x3EC36, Size = 0x159D3, IsPacked = true }, + new PackedEntry { Name = "Hb14_06b.gem", Type = "image", Offset = 0x86EE16, UnpackedSize = 0x3EC36, Size = 0x3C0F, IsPacked = true }, + new PackedEntry { Name = "Hb14_06c.gem", Type = "image", Offset = 0x872A25, UnpackedSize = 0x3EC36, Size = 0x7DF5, IsPacked = true }, + new PackedEntry { Name = "Hb14_06d.gem", Type = "image", Offset = 0x87A81A, UnpackedSize = 0x3EC36, Size = 0x1B8A, IsPacked = true }, + new PackedEntry { Name = "Hb14_07.gps", Type = "image", Offset = 0x87C3A4, UnpackedSize = 0x3EC36, Size = 0x168D0, IsPacked = true }, + new PackedEntry { Name = "Hb14_08a.gps", Type = "image", Offset = 0x892C74, UnpackedSize = 0x3EC36, Size = 0x1A952, IsPacked = true }, + new PackedEntry { Name = "Hb14_08b.gem", Type = "image", Offset = 0x8AD5C6, UnpackedSize = 0x3EC36, Size = 0x2362, IsPacked = true }, + new PackedEntry { Name = "Hb14_e01.gps", Type = "image", Offset = 0x8AF928, UnpackedSize = 0x3EC36, Size = 0x1EF08, IsPacked = true }, + new PackedEntry { Name = "Hb14_e02.gps", Type = "image", Offset = 0x8CE830, UnpackedSize = 0x3EC36, Size = 0x230F5, IsPacked = true }, + new PackedEntry { Name = "Hb15_01.gps", Type = "image", Offset = 0x8F1925, UnpackedSize = 0x28436, Size = 0x15781, IsPacked = true }, + new PackedEntry { Name = "Hb15_02.gps", Type = "image", Offset = 0x9070A6, UnpackedSize = 0x28436, Size = 0x19206, IsPacked = true }, + new PackedEntry { Name = "Hb15_03.gps", Type = "image", Offset = 0x9202AC, UnpackedSize = 0x28836, Size = 0x188E5, IsPacked = true }, + new PackedEntry { Name = "Hb15_04.gps", Type = "image", Offset = 0x938B91, UnpackedSize = 0x28436, Size = 0x1630C, IsPacked = true }, + new PackedEntry { Name = "Hb15_05.gem", Type = "image", Offset = 0x94EE9D, UnpackedSize = 0x3EC36, Size = 0x1144F, IsPacked = true }, + new PackedEntry { Name = "Hb15_06a.gps", Type = "image", Offset = 0x9602EC, UnpackedSize = 0x3EC36, Size = 0x19313, IsPacked = true }, + new PackedEntry { Name = "Hb15_06b.gem", Type = "image", Offset = 0x9795FF, UnpackedSize = 0x3EC36, Size = 0x0C102, IsPacked = true }, + new PackedEntry { Name = "Hb15_06c.gem", Type = "image", Offset = 0x985701, UnpackedSize = 0x3EC36, Size = 0x0AF19, IsPacked = true }, + new PackedEntry { Name = "Hb15_06d.gem", Type = "image", Offset = 0x99061A, UnpackedSize = 0x3EC36, Size = 0x1FD5, IsPacked = true }, + new PackedEntry { Name = "Hb15_07.gps", Type = "image", Offset = 0x9925EF, UnpackedSize = 0x3EC36, Size = 0x1BE25, IsPacked = true }, + new PackedEntry { Name = "Hb15_08a.gps", Type = "image", Offset = 0x9AE414, UnpackedSize = 0x3EC36, Size = 0x1B2C3, IsPacked = true }, + new PackedEntry { Name = "Hb15_08b.gem", Type = "image", Offset = 0x9C96D7, UnpackedSize = 0x3EC36, Size = 0x412C, IsPacked = true }, + new PackedEntry { Name = "Hb15_e01.gps", Type = "image", Offset = 0x9CD803, UnpackedSize = 0x3EC36, Size = 0x1E116, IsPacked = true }, + new PackedEntry { Name = "Hb15_e02.gps", Type = "image", Offset = 0x9EB919, UnpackedSize = 0x3EC36, Size = 0x1A31C, IsPacked = true }, + new PackedEntry { Name = "Hb16_01.gps", Type = "image", Offset = 0x0A05C35, UnpackedSize = 0x28436, Size = 0x12066, IsPacked = true }, + new PackedEntry { Name = "Hb16_02.gps", Type = "image", Offset = 0x0A17C9B, UnpackedSize = 0x28436, Size = 0x16EE0, IsPacked = true }, + new PackedEntry { Name = "Hb16_03.gem", Type = "image", Offset = 0x0A2EB7B, UnpackedSize = 0x3EC36, Size = 0x12E21, IsPacked = true }, + new PackedEntry { Name = "Hb16_04.gps", Type = "image", Offset = 0x0A4199C, UnpackedSize = 0x28436, Size = 0x1554E, IsPacked = true }, + new PackedEntry { Name = "Hb16_05a.gps", Type = "image", Offset = 0x0A56EEA, UnpackedSize = 0x3EC36, Size = 0x14F0D, IsPacked = true }, + new PackedEntry { Name = "Hb16_05b.gem", Type = "image", Offset = 0x0A6BDF7, UnpackedSize = 0x3EC36, Size = 0x113A8, IsPacked = true }, + new PackedEntry { Name = "Hb16_05c.gem", Type = "image", Offset = 0x0A7D19F, UnpackedSize = 0x3EC36, Size = 0x6925, IsPacked = true }, + new PackedEntry { Name = "Hb16_05d.gem", Type = "image", Offset = 0x0A83AC4, UnpackedSize = 0x3EC36, Size = 0x2853, IsPacked = true }, + new PackedEntry { Name = "Hb16_06.gps", Type = "image", Offset = 0x0A86317, UnpackedSize = 0x3EC36, Size = 0x16A4A, IsPacked = true }, + new PackedEntry { Name = "Hb16_07.gps", Type = "image", Offset = 0x0A9CD61, UnpackedSize = 0x3EC36, Size = 0x1456F, IsPacked = true }, + new PackedEntry { Name = "Hb16_08a.gps", Type = "image", Offset = 0x0AB12D0, UnpackedSize = 0x3EC36, Size = 0x17724, IsPacked = true }, + new PackedEntry { Name = "Hb16_08b.gem", Type = "image", Offset = 0x0AC89F4, UnpackedSize = 0x3EC36, Size = 0x2444, IsPacked = true }, + new PackedEntry { Name = "Hb16_e01.gps", Type = "image", Offset = 0x0ACAE38, UnpackedSize = 0x3EC36, Size = 0x2A0A6, IsPacked = true }, + new PackedEntry { Name = "Hb16_e02.gps", Type = "image", Offset = 0x0AF4EDE, UnpackedSize = 0x3EC36, Size = 0x238DD, IsPacked = true }, + new PackedEntry { Name = "Hb17_01.gps", Type = "image", Offset = 0x0B187BB, UnpackedSize = 0x28436, Size = 0x1801C, IsPacked = true }, + new PackedEntry { Name = "Hb17_02.gps", Type = "image", Offset = 0x0B307D7, UnpackedSize = 0x28436, Size = 0x13D41, IsPacked = true }, + new PackedEntry { Name = "Hb17_03a.gps", Type = "image", Offset = 0x0B44518, UnpackedSize = 0x3EC36, Size = 0x13B51, IsPacked = true }, + new PackedEntry { Name = "Hb17_03b.gem", Type = "image", Offset = 0x0B58069, UnpackedSize = 0x3EC36, Size = 0x0D070, IsPacked = true }, + new PackedEntry { Name = "Hb17_03c.gem", Type = "image", Offset = 0x0B650D9, UnpackedSize = 0x3EC36, Size = 0x7809, IsPacked = true }, + new PackedEntry { Name = "Hb17_04a.gps", Type = "image", Offset = 0x0B6C8E2, UnpackedSize = 0x3EC36, Size = 0x1AD4F, IsPacked = true }, + new PackedEntry { Name = "Hb17_04b.gem", Type = "image", Offset = 0x0B87631, UnpackedSize = 0x3EC36, Size = 0x2359, IsPacked = true }, + new PackedEntry { Name = "Hb17_05.gps", Type = "image", Offset = 0x0B8998A, UnpackedSize = 0x3EC36, Size = 0x1D87E, IsPacked = true }, + new PackedEntry { Name = "Hb17_e01.gps", Type = "image", Offset = 0x0BA7208, UnpackedSize = 0x3EC36, Size = 0x2290B, IsPacked = true }, + new PackedEntry { Name = "Hb17_e02.gps", Type = "image", Offset = 0x0BC9B13, UnpackedSize = 0x3EC36, Size = 0x1F73F, IsPacked = true }, + new PackedEntry { Name = "Hb18_01.gem", Type = "image", Offset = 0x0BE9252, UnpackedSize = 0x3EC36, Size = 0x1895B, IsPacked = true }, + new PackedEntry { Name = "Hb18_02a.gps", Type = "image", Offset = 0x0C01BAD, UnpackedSize = 0x3EC36, Size = 0x1D715, IsPacked = true }, + new PackedEntry { Name = "Hb18_02b.gem", Type = "image", Offset = 0x0C1F2C2, UnpackedSize = 0x3EC36, Size = 0x1DE3, IsPacked = true }, + new PackedEntry { Name = "Hb18_03.gps", Type = "image", Offset = 0x0C210A5, UnpackedSize = 0x3EC36, Size = 0x15C41, IsPacked = true }, + new PackedEntry { Name = "Hb18_04a.gps", Type = "image", Offset = 0x0C36CE6, UnpackedSize = 0x3EC36, Size = 0x16CE3, IsPacked = true }, + new PackedEntry { Name = "Hb18_04b.gem", Type = "image", Offset = 0x0C4D9C9, UnpackedSize = 0x3EC36, Size = 0x29B5, IsPacked = true }, + new PackedEntry { Name = "Hb18_05.gps", Type = "image", Offset = 0x0C5037E, UnpackedSize = 0x28436, Size = 0x19472, IsPacked = true }, + new PackedEntry { Name = "Hb18_06.gps", Type = "image", Offset = 0x0C697F0, UnpackedSize = 0x28436, Size = 0x17046, IsPacked = true }, + new PackedEntry { Name = "Hb18_e01.gps", Type = "image", Offset = 0x0C80836, UnpackedSize = 0x3EC36, Size = 0x1D572, IsPacked = true }, + new PackedEntry { Name = "Hb18_e02.gps", Type = "image", Offset = 0x0C9DDA8, UnpackedSize = 0x3EC36, Size = 0x1B241, IsPacked = true }, + new PackedEntry { Name = "Hb19_01.gem", Type = "image", Offset = 0x0CB8FE9, UnpackedSize = 0x3EC36, Size = 0x1A34D, IsPacked = true }, + new PackedEntry { Name = "Hb19_02.gps", Type = "image", Offset = 0x0CD3336, UnpackedSize = 0x3EC36, Size = 0x18208, IsPacked = true }, + new PackedEntry { Name = "Hb19_03.gps", Type = "image", Offset = 0x0CEB53E, UnpackedSize = 0x28436, Size = 0x1855A, IsPacked = true }, + new PackedEntry { Name = "Hb19_04.gps", Type = "image", Offset = 0x0D03A98, UnpackedSize = 0x28436, Size = 0x1411A, IsPacked = true }, + new PackedEntry { Name = "Hb19_05a.gps", Type = "image", Offset = 0x0D17BB2, UnpackedSize = 0x3EC36, Size = 0x22611, IsPacked = true }, + new PackedEntry { Name = "Hb19_05b.gem", Type = "image", Offset = 0x0D3A1C3, UnpackedSize = 0x3EC36, Size = 0x98D0, IsPacked = true }, + new PackedEntry { Name = "Hb19_05c.gem", Type = "image", Offset = 0x0D43A93, UnpackedSize = 0x3EC36, Size = 0x7B0E, IsPacked = true }, + new PackedEntry { Name = "Hb19_05d.gem", Type = "image", Offset = 0x0D4B5A1, UnpackedSize = 0x3EC36, Size = 0x2603, IsPacked = true }, + new PackedEntry { Name = "Hb19_06.gps", Type = "image", Offset = 0x0D4DBA4, UnpackedSize = 0x3EC36, Size = 0x1A2AB, IsPacked = true }, + new PackedEntry { Name = "Hb19_07.gps", Type = "image", Offset = 0x0D67E4F, UnpackedSize = 0x3EC36, Size = 0x190E7, IsPacked = true }, + new PackedEntry { Name = "Hb19_08a.gps", Type = "image", Offset = 0x0D80F36, UnpackedSize = 0x3EC36, Size = 0x175F8, IsPacked = true }, + new PackedEntry { Name = "Hb19_08b.gem", Type = "image", Offset = 0x0D9852E, UnpackedSize = 0x3EC36, Size = 0x33B4, IsPacked = true }, + new PackedEntry { Name = "Hb19_e01.gps", Type = "image", Offset = 0x0D9B8E2, UnpackedSize = 0x3EC36, Size = 0x262C3, IsPacked = true }, + new PackedEntry { Name = "Hb19_e02.gps", Type = "image", Offset = 0x0DC1BA5, UnpackedSize = 0x3EC36, Size = 0x20CA0, IsPacked = true }, + new PackedEntry { Name = "Hb19_uta.gps", Type = "image", Offset = 0x0DE2845, UnpackedSize = 0x28836, Size = 0x4339, IsPacked = true }, + new PackedEntry { Name = "Hb20_01.gps", Type = "image", Offset = 0x0DE6B7E, UnpackedSize = 0x28436, Size = 0x15778, IsPacked = true }, + new PackedEntry { Name = "Hb20_02.gps", Type = "image", Offset = 0x0DFC2F6, UnpackedSize = 0x28436, Size = 0x147D2, IsPacked = true }, + new PackedEntry { Name = "Hb20_03.gps", Type = "image", Offset = 0x0E10AC8, UnpackedSize = 0x28436, Size = 0x161D5, IsPacked = true }, + new PackedEntry { Name = "Hb20_04a.gps", Type = "image", Offset = 0x0E26C9D, UnpackedSize = 0x3EC36, Size = 0x20333, IsPacked = true }, + new PackedEntry { Name = "Hb20_04b.gem", Type = "image", Offset = 0x0E46FD0, UnpackedSize = 0x3EC36, Size = 0x9BE9, IsPacked = true }, + new PackedEntry { Name = "Hb20_04c.gem", Type = "image", Offset = 0x0E50BB9, UnpackedSize = 0x3EC36, Size = 0x2426, IsPacked = true }, + new PackedEntry { Name = "Hb20_05.gps", Type = "image", Offset = 0x0E52FDF, UnpackedSize = 0x3EC36, Size = 0x271A7, IsPacked = true }, + new PackedEntry { Name = "Hb20_06.gps", Type = "image", Offset = 0x0E7A186, UnpackedSize = 0x3EC36, Size = 0x190EA, IsPacked = true }, + new PackedEntry { Name = "Hb20_07a.gps", Type = "image", Offset = 0x0E93270, UnpackedSize = 0x3EC36, Size = 0x16FCC, IsPacked = true }, + new PackedEntry { Name = "Hb20_07b.gem", Type = "image", Offset = 0x0EAA23C, UnpackedSize = 0x3EC36, Size = 0x2220, IsPacked = true }, + new PackedEntry { Name = "Hb20_e01.gps", Type = "image", Offset = 0x0EAC45C, UnpackedSize = 0x3EC36, Size = 0x1FAF6, IsPacked = true }, + new PackedEntry { Name = "Hb20_e02.gps", Type = "image", Offset = 0x0ECBF52, UnpackedSize = 0x3EC36, Size = 0x28199, IsPacked = true }, + new PackedEntry { Name = "Hb21_01.gps", Type = "image", Offset = 0x0EF40EB, UnpackedSize = 0x28436, Size = 0x11248, IsPacked = true }, + new PackedEntry { Name = "Hb21_02.gps", Type = "image", Offset = 0x0F05333, UnpackedSize = 0x28436, Size = 0x118B4, IsPacked = true }, + new PackedEntry { Name = "Hb21_03.gps", Type = "image", Offset = 0x0F16BE7, UnpackedSize = 0x28436, Size = 0x0DE2D, IsPacked = true }, + new PackedEntry { Name = "Hb21_04.gps", Type = "image", Offset = 0x0F24A14, UnpackedSize = 0x28436, Size = 0x0FFD8, IsPacked = true }, + new PackedEntry { Name = "Hb21_05.gps", Type = "image", Offset = 0x0F349EC, UnpackedSize = 0x28436, Size = 0x16D32, IsPacked = true }, + new PackedEntry { Name = "Hb21_06.gps", Type = "image", Offset = 0x0F4B71E, UnpackedSize = 0x28436, Size = 0x1406C, IsPacked = true }, + new PackedEntry { Name = "Hb21_07.gps", Type = "image", Offset = 0x0F5F78A, UnpackedSize = 0x3EC36, Size = 0x22B2A, IsPacked = true }, + new PackedEntry { Name = "Hb21_08a.gps", Type = "image", Offset = 0x0F822B4, UnpackedSize = 0x3EC36, Size = 0x191DF, IsPacked = true }, + new PackedEntry { Name = "Hb21_08b.gem", Type = "image", Offset = 0x0F9B493, UnpackedSize = 0x3EC36, Size = 0x1FCA, IsPacked = true }, + new PackedEntry { Name = "Hb21_08c.gem", Type = "image", Offset = 0x0F9D45D, UnpackedSize = 0x3EC36, Size = 0x10B2, IsPacked = true }, + new PackedEntry { Name = "Hb21_08d.gem", Type = "image", Offset = 0x0F9E50F, UnpackedSize = 0x3EC36, Size = 0x1075, IsPacked = true }, + new PackedEntry { Name = "Hb21_08e.gem", Type = "image", Offset = 0x0F9F584, UnpackedSize = 0x3EC36, Size = 0x1092, IsPacked = true }, + new PackedEntry { Name = "Hb21_08f.gem", Type = "image", Offset = 0x0FA0616, UnpackedSize = 0x3EC36, Size = 0x1101, IsPacked = true }, + new PackedEntry { Name = "Hb21_08g.gem", Type = "image", Offset = 0x0FA1717, UnpackedSize = 0x3EC36, Size = 0x1113, IsPacked = true }, + new PackedEntry { Name = "Hb21_e01.gps", Type = "image", Offset = 0x0FA282A, UnpackedSize = 0x3EC36, Size = 0x2155D, IsPacked = true }, + new PackedEntry { Name = "Hb21_e02.gps", Type = "image", Offset = 0x0FC3D87, UnpackedSize = 0x3EC36, Size = 0x1E3DF, IsPacked = true }, + new PackedEntry { Name = "Hb26_01.gem", Type = "image", Offset = 0x0FE2166, UnpackedSize = 0x3EC36, Size = 0x12C17, IsPacked = true }, + new PackedEntry { Name = "Hb26_02.gps", Type = "image", Offset = 0x0FF4D7D, UnpackedSize = 0x28436, Size = 0x18804, IsPacked = true }, + new PackedEntry { Name = "Hb26_03.gem", Type = "image", Offset = 0x100D581, UnpackedSize = 0x3EC36, Size = 0x16091, IsPacked = true }, + new PackedEntry { Name = "Hb26_04a.gps", Type = "image", Offset = 0x1023612, UnpackedSize = 0x3EC36, Size = 0x17ECF, IsPacked = true }, + new PackedEntry { Name = "Hb26_04b.gem", Type = "image", Offset = 0x103B4E1, UnpackedSize = 0x3EC36, Size = 0x0CACC, IsPacked = true }, + new PackedEntry { Name = "Hb26_04c.gem", Type = "image", Offset = 0x1047FAD, UnpackedSize = 0x3EC36, Size = 0x9BEB, IsPacked = true }, + new PackedEntry { Name = "Hb26_05.gps", Type = "image", Offset = 0x1051B98, UnpackedSize = 0x3EC36, Size = 0x1D990, IsPacked = true }, + new PackedEntry { Name = "Hb26_06.gps", Type = "image", Offset = 0x106F528, UnpackedSize = 0x3EC36, Size = 0x22899, IsPacked = true }, + new PackedEntry { Name = "Hb26_e01.gps", Type = "image", Offset = 0x1091DC1, UnpackedSize = 0x3EC36, Size = 0x1E7D1, IsPacked = true }, + new PackedEntry { Name = "Hb26_e02.gps", Type = "image", Offset = 0x10B0592, UnpackedSize = 0x3EC36, Size = 0x24B98, IsPacked = true }, + new PackedEntry { Name = "Hbev_01.gps", Type = "image", Offset = 0x10D512A, UnpackedSize = 0x28436, Size = 0x16501, IsPacked = true }, + new PackedEntry { Name = "Hbev_02.gps", Type = "image", Offset = 0x10EB62B, UnpackedSize = 0x28436, Size = 0x1E057, IsPacked = true }, + new PackedEntry { Name = "Hbev_03.gps", Type = "image", Offset = 0x1109682, UnpackedSize = 0x28436, Size = 0x185EE, IsPacked = true }, + new PackedEntry { Name = "Hbev_04.gps", Type = "image", Offset = 0x1121C70, UnpackedSize = 0x3EC36, Size = 0x2208A, IsPacked = true }, + new PackedEntry { Name = "Hbop_02.gem", Type = "image", Offset = 0x1143CFA, UnpackedSize = 0x3EC36, Size = 0x194EB, IsPacked = true }, + new PackedEntry { Name = "Hbop_03.gem", Type = "image", Offset = 0x115D1E5, UnpackedSize = 0x3EC36, Size = 0x21063, IsPacked = true }, + new PackedEntry { Name = "Hbop_04.gps", Type = "image", Offset = 0x117E248, UnpackedSize = 0x3EC36, Size = 0x1D54D, IsPacked = true }, + new PackedEntry { Name = "Hbop_05.gem", Type = "image", Offset = 0x119B795, UnpackedSize = 0x3EC36, Size = 0x32A86, IsPacked = true }, + new PackedEntry { Name = "Hb_moji.gps", Type = "image", Offset = 0x11CE21B, UnpackedSize = 0x1B96, Size = 0x38F, IsPacked = true }, + new PackedEntry { Name = "Hb_roll0.gem", Type = "image", Offset = 0x11CE5AA, UnpackedSize = 0x3EC36, Size = 0x1B59, IsPacked = true }, + new PackedEntry { Name = "Hb_roll1.gem", Type = "image", Offset = 0x11D0103, UnpackedSize = 0x3EC36, Size = 0x2106, IsPacked = true }, + new PackedEntry { Name = "Hb_roll2.gem", Type = "image", Offset = 0x11D2209, UnpackedSize = 0x3EC36, Size = 0x2287, IsPacked = true }, + new PackedEntry { Name = "Hb_roll3.gem", Type = "image", Offset = 0x11D4490, UnpackedSize = 0x3EC36, Size = 0x261A, IsPacked = true }, + new PackedEntry { Name = "Hb_roll4.gem", Type = "image", Offset = 0x11D6AAA, UnpackedSize = 0x3EC36, Size = 0x1594, IsPacked = true }, + new PackedEntry { Name = "Kana.gem", Type = "image", Offset = 0x11D803E, UnpackedSize = 0x3EC36, Size = 0x1A76, IsPacked = true }, + new PackedEntry { Name = "K_abel.gem", Type = "image", Offset = 0x11D9AB4, UnpackedSize = 0x19436, Size = 0x0A5CB, IsPacked = true }, + new PackedEntry { Name = "K_annin.gem", Type = "image", Offset = 0x11E407F, UnpackedSize = 0x17B36, Size = 0x87CA, IsPacked = true }, + new PackedEntry { Name = "K_bajil.gem", Type = "image", Offset = 0x11EC849, UnpackedSize = 0x187B6, Size = 0x8E93, IsPacked = true }, + new PackedEntry { Name = "K_bobes.gem", Type = "image", Offset = 0x11F56DC, UnpackedSize = 0x24FB6, Size = 0x0FD0F, IsPacked = true }, + new PackedEntry { Name = "K_bosco.gem", Type = "image", Offset = 0x12053EB, UnpackedSize = 0x19436, Size = 0x0B246, IsPacked = true }, + new PackedEntry { Name = "K_clim1.gem", Type = "image", Offset = 0x1210631, UnpackedSize = 0x187B6, Size = 0x8232, IsPacked = true }, + new PackedEntry { Name = "K_clim2.gem", Type = "image", Offset = 0x1218863, UnpackedSize = 0x349B6, Size = 0x10D9B, IsPacked = true }, + new PackedEntry { Name = "K_cura.gem", Type = "image", Offset = 0x12295FE, UnpackedSize = 0x19436, Size = 0x0AD4B, IsPacked = true }, + new PackedEntry { Name = "K_gana1.gem", Type = "image", Offset = 0x1234349, UnpackedSize = 0x17B36, Size = 0x96BE, IsPacked = true }, + new PackedEntry { Name = "K_gana2.gem", Type = "image", Offset = 0x123DA07, UnpackedSize = 0x17B36, Size = 0x72D0, IsPacked = true }, + new PackedEntry { Name = "K_king.gem", Type = "image", Offset = 0x1244CD7, UnpackedSize = 0x17B36, Size = 0x8D33, IsPacked = true }, + new PackedEntry { Name = "K_mafi1.gem", Type = "image", Offset = 0x124DA0A, UnpackedSize = 0x13CB6, Size = 0x60F9, IsPacked = true }, + new PackedEntry { Name = "K_mafi2.gem", Type = "image", Offset = 0x1253B03, UnpackedSize = 0x17B36, Size = 0x58DB, IsPacked = true }, + new PackedEntry { Name = "K_mafin1.gem", Type = "image", Offset = 0x12593DE, UnpackedSize = 0x13CB6, Size = 0x60F9, IsPacked = true }, + new PackedEntry { Name = "K_mafin2.gem", Type = "image", Offset = 0x125F4D7, UnpackedSize = 0x17B36, Size = 0x58DB, IsPacked = true }, + new PackedEntry { Name = "K_mcsr.gps", Type = "image", Offset = 0x1264DB2, UnpackedSize = 0x5436, Size = 0x3A8, IsPacked = true }, + new PackedEntry { Name = "K_milf1.gem", Type = "image", Offset = 0x126515A, UnpackedSize = 0x236B6, Size = 0x0C081, IsPacked = true }, + new PackedEntry { Name = "K_milf2.gem", Type = "image", Offset = 0x12711DB, UnpackedSize = 0x1DF36, Size = 0x8839, IsPacked = true }, + new PackedEntry { Name = "K_panna.gem", Type = "image", Offset = 0x1279A14, UnpackedSize = 0x1EBB6, Size = 0x0B8F8, IsPacked = true }, + new PackedEntry { Name = "K_ponti.gem", Type = "image", Offset = 0x128530C, UnpackedSize = 0x268B6, Size = 0x0FD6A, IsPacked = true }, + new PackedEntry { Name = "K_queen.gem", Type = "image", Offset = 0x1295076, UnpackedSize = 0x16236, Size = 0x0AA57, IsPacked = true }, + new PackedEntry { Name = "K_riqu1.gem", Type = "image", Offset = 0x129FACD, UnpackedSize = 0x1A0B6, Size = 0x7AB9, IsPacked = true }, + new PackedEntry { Name = "K_riqu2.gem", Type = "image", Offset = 0x12A7586, UnpackedSize = 0x1B9B6, Size = 0x5818, IsPacked = true }, + new PackedEntry { Name = "K_riqur1.gem", Type = "image", Offset = 0x12ACD9E, UnpackedSize = 0x1A0B6, Size = 0x88A7, IsPacked = true }, + new PackedEntry { Name = "K_riqur2.gem", Type = "image", Offset = 0x12B5645, UnpackedSize = 0x1B9B6, Size = 0x5818, IsPacked = true }, + new PackedEntry { Name = "K_russ1.gem", Type = "image", Offset = 0x12BAE5D, UnpackedSize = 0x1A0B6, Size = 0x9633, IsPacked = true }, + new PackedEntry { Name = "K_russ2.gem", Type = "image", Offset = 0x12C4490, UnpackedSize = 0x236B6, Size = 0x0B5D3, IsPacked = true }, + new PackedEntry { Name = "K_sable.gem", Type = "image", Offset = 0x12CFA63, UnpackedSize = 0x19436, Size = 0x95C2, IsPacked = true }, + new PackedEntry { Name = "K_seli1.gem", Type = "image", Offset = 0x12D9025, UnpackedSize = 0x1DF36, Size = 0x7BE8, IsPacked = true }, + new PackedEntry { Name = "K_seli2.gem", Type = "image", Offset = 0x12E0C0D, UnpackedSize = 0x19436, Size = 0x7254, IsPacked = true }, + new PackedEntry { Name = "K_selis1.gem", Type = "image", Offset = 0x12E7E61, UnpackedSize = 0x1DF36, Size = 0x7BE8, IsPacked = true }, + new PackedEntry { Name = "K_selis2.gem", Type = "image", Offset = 0x12EFA49, UnpackedSize = 0x19436, Size = 0x7254, IsPacked = true }, + new PackedEntry { Name = "K_shake.gem", Type = "image", Offset = 0x12F6C9D, UnpackedSize = 0x1A0B6, Size = 0x77C4, IsPacked = true }, + new PackedEntry { Name = "K_syoko.gem", Type = "image", Offset = 0x12FE461, UnpackedSize = 0x12436, Size = 0x5E67, IsPacked = true }, + new PackedEntry { Name = "K_syuku.gem", Type = "image", Offset = 0x13042C8, UnpackedSize = 0x187B6, Size = 0x76C9, IsPacked = true }, + new PackedEntry { Name = "K_tira.gem", Type = "image", Offset = 0x130B991, UnpackedSize = 0x24336, Size = 0x928C, IsPacked = true }, + new PackedEntry { Name = "K_tolte.gem", Type = "image", Offset = 0x1314C1D, UnpackedSize = 0x1B9B6, Size = 0x8670, IsPacked = true }, + new PackedEntry { Name = "K_tryu.gem", Type = "image", Offset = 0x131D28D, UnpackedSize = 0x16236, Size = 0x8A06, IsPacked = true }, + new PackedEntry { Name = "Load.gem", Type = "image", Offset = 0x1325C93, UnpackedSize = 0x3EC36, Size = 0x4937, IsPacked = true }, + new PackedEntry { Name = "Man_bg.gps", Type = "image", Offset = 0x132A5CA, UnpackedSize = 0x3EC36, Size = 0x0D6A4, IsPacked = true }, + new PackedEntry { Name = "Mapwin.gem", Type = "image", Offset = 0x1337C6E, UnpackedSize = 0x3EC36, Size = 0x2236, IsPacked = true }, + new PackedEntry { Name = "Mcsr.gps", Type = "image", Offset = 0x1339EA4, UnpackedSize = 0x5436, Size = 0x3B9, IsPacked = true }, + new PackedEntry { Name = "Oki.gem", Type = "image", Offset = 0x133A25D, UnpackedSize = 0x3EC36, Size = 0x45DB, IsPacked = true }, + new PackedEntry { Name = "Opt_bg.gps", Type = "image", Offset = 0x133E838, UnpackedSize = 0x3EC36, Size = 0x1E5A, IsPacked = true }, + new PackedEntry { Name = "Opt_bgm.gem", Type = "image", Offset = 0x1340692, UnpackedSize = 0x3EC36, Size = 0x0EE0, IsPacked = true }, + new PackedEntry { Name = "Opt_cgm.gem", Type = "image", Offset = 0x1341572, UnpackedSize = 0x3EC36, Size = 0x0EAA, IsPacked = true }, + new PackedEntry { Name = "Opt_manu.gem", Type = "image", Offset = 0x134241C, UnpackedSize = 0x3EC36, Size = 0x0EB8, IsPacked = true }, + new PackedEntry { Name = "Op_05x.gem", Type = "image", Offset = 0x13432D4, UnpackedSize = 0x3EC36, Size = 0x10ED3, IsPacked = true }, + new PackedEntry { Name = "Op_06a.gem", Type = "image", Offset = 0x13541A7, UnpackedSize = 0x3EC36, Size = 0x7843, IsPacked = true }, + new PackedEntry { Name = "Op_06b.gem", Type = "image", Offset = 0x135B9EA, UnpackedSize = 0x3EC36, Size = 0x7F21, IsPacked = true }, + new PackedEntry { Name = "Op_06c.gem", Type = "image", Offset = 0x136390B, UnpackedSize = 0x3EC36, Size = 0x8F06, IsPacked = true }, + new PackedEntry { Name = "Op_06d.gem", Type = "image", Offset = 0x136C811, UnpackedSize = 0x3EC36, Size = 0x0A93A, IsPacked = true }, + new PackedEntry { Name = "Op_07a.gem", Type = "image", Offset = 0x137714B, UnpackedSize = 0x1D236, Size = 0x3451, IsPacked = true }, + new PackedEntry { Name = "Op_07b.gem", Type = "image", Offset = 0x137A59C, UnpackedSize = 0x3EC36, Size = 0x3B9E, IsPacked = true }, + new PackedEntry { Name = "Op_07m.gem", Type = "image", Offset = 0x137E13A, UnpackedSize = 0x1D236, Size = 0x0AC9, IsPacked = true }, + new PackedEntry { Name = "Op_08.gem", Type = "image", Offset = 0x137EC03, UnpackedSize = 0x3EC36, Size = 0x6AE6, IsPacked = true }, + new PackedEntry { Name = "Op_18x.gem", Type = "image", Offset = 0x13856E9, UnpackedSize = 0x3EC36, Size = 0x317F, IsPacked = true }, + new PackedEntry { Name = "Op_26x.gem", Type = "image", Offset = 0x1388868, UnpackedSize = 0x3EC36, Size = 0x4FCF, IsPacked = true }, + new PackedEntry { Name = "Op_29x.gem", Type = "image", Offset = 0x138D837, UnpackedSize = 0x3EC36, Size = 0x0C8FE, IsPacked = true }, + new PackedEntry { Name = "Op_32x.gem", Type = "image", Offset = 0x139A135, UnpackedSize = 0x3EC36, Size = 0x5BCB, IsPacked = true }, + new PackedEntry { Name = "Op_34x.gem", Type = "image", Offset = 0x139FD00, UnpackedSize = 0x3EC36, Size = 0x680A, IsPacked = true }, + new PackedEntry { Name = "Op_35x.gem", Type = "image", Offset = 0x13A650A, UnpackedSize = 0x3EC36, Size = 0x8D76, IsPacked = true }, + new PackedEntry { Name = "Op_36x.gem", Type = "image", Offset = 0x13AF280, UnpackedSize = 0x3EC36, Size = 0x9C34, IsPacked = true }, + new PackedEntry { Name = "Op_37x.gem", Type = "image", Offset = 0x13B8EB4, UnpackedSize = 0x3EC36, Size = 0x90B8, IsPacked = true }, + new PackedEntry { Name = "Op_tate.gem", Type = "image", Offset = 0x13C1F6C, UnpackedSize = 0x3EC36, Size = 0x75C7, IsPacked = true }, + new PackedEntry { Name = "Save.gem", Type = "image", Offset = 0x13C9533, UnpackedSize = 0x3EC36, Size = 0x4987, IsPacked = true }, + new PackedEntry { Name = "Shop.gem", Type = "image", Offset = 0x13CDEBA, UnpackedSize = 0x3EC36, Size = 0x2FE0, IsPacked = true }, + new PackedEntry { Name = "Start_t.gps", Type = "image", Offset = 0x13D0E9A, UnpackedSize = 0x3EC36, Size = 0x6EB2, IsPacked = true }, + new PackedEntry { Name = "Stat_a.gem", Type = "image", Offset = 0x13D7D4C, UnpackedSize = 0x3EC36, Size = 0x465A, IsPacked = true }, + new PackedEntry { Name = "Stat_b.gem", Type = "image", Offset = 0x13DC3A6, UnpackedSize = 0x3EC36, Size = 0x262B, IsPacked = true }, + new PackedEntry { Name = "St_ann.gem", Type = "image", Offset = 0x13DE9D1, UnpackedSize = 0x3EC36, Size = 0x278A, IsPacked = true }, + new PackedEntry { Name = "St_cain.gem", Type = "image", Offset = 0x13E115B, UnpackedSize = 0x3EC36, Size = 0x27F8, IsPacked = true }, + new PackedEntry { Name = "St_clim.gem", Type = "image", Offset = 0x13E3953, UnpackedSize = 0x3EC36, Size = 0x2558, IsPacked = true }, + new PackedEntry { Name = "St_pon.gem", Type = "image", Offset = 0x13E5EAB, UnpackedSize = 0x3EC36, Size = 0x3A07, IsPacked = true }, + new PackedEntry { Name = "St_riq.gem", Type = "image", Offset = 0x13E98B2, UnpackedSize = 0x3EC36, Size = 0x25CA, IsPacked = true }, + new PackedEntry { Name = "St_russ.gem", Type = "image", Offset = 0x13EBE7C, UnpackedSize = 0x3EC36, Size = 0x2885, IsPacked = true }, + new PackedEntry { Name = "Tai.gps", Type = "image", Offset = 0x13EE701, UnpackedSize = 0x3EC36, Size = 0x3D79, IsPacked = true }, + new PackedEntry { Name = "Tit.gps", Type = "image", Offset = 0x13F247A, UnpackedSize = 0x3EC36, Size = 0x5EDE, IsPacked = true }, + new PackedEntry { Name = "Title_de.gem", Type = "image", Offset = 0x13F8358, UnpackedSize = 0x3EC36, Size = 0x3D6C, IsPacked = true }, + new PackedEntry { Name = "T_mcsr.gps", Type = "image", Offset = 0x13FC0C4, UnpackedSize = 0x5436, Size = 0x244, IsPacked = true }, + new PackedEntry { Name = "Wipe.gem", Type = "image", Offset = 0x13FC308, UnpackedSize = 0x3EC36, Size = 0x25BE, IsPacked = true }, + new PackedEntry { Name = "Wiz.gps", Type = "image", Offset = 0x13FE8C6, UnpackedSize = 0x3EC36, Size = 0x675A, IsPacked = true }, + new PackedEntry { Name = "Bat.bmp", Type = "image", Offset = 0x1405020, UnpackedSize = 0x259E, Size = 0x6E9, IsPacked = true }, + new PackedEntry { Name = "Cgco.bmp", Type = "image", Offset = 0x1405709, UnpackedSize = 0x3EBEE, Size = 0x193FD, IsPacked = true }, + new PackedEntry { Name = "Hb_roll5.bmp", Type = "image", Offset = 0x141EB06, UnpackedSize = 0x3EC38, Size = 0x1499, IsPacked = true }, + new PackedEntry { Name = "Hi.bmp", Type = "image", Offset = 0x141FF9F, UnpackedSize = 0x213E, Size = 0x747, IsPacked = true }, + new PackedEntry { Name = "Off.bmp", Type = "image", Offset = 0x14206E6, UnpackedSize = 0x0D4E, Size = 0x51B, IsPacked = true }, + new PackedEntry { Name = "Off2.bmp", Type = "image", Offset = 0x1420C01, UnpackedSize = 0x0D4E, Size = 0x51B, IsPacked = true }, + new PackedEntry { Name = "On.bmp", Type = "image", Offset = 0x142111C, UnpackedSize = 0x0AF6, Size = 0x51A, IsPacked = true }, + new PackedEntry { Name = "On2.bmp", Type = "image", Offset = 0x1421636, UnpackedSize = 0x0AF6, Size = 0x51A, IsPacked = true }, + new PackedEntry { Name = "Qui.bmp", Type = "image", Offset = 0x1421B50, UnpackedSize = 0x1686, Size = 0x5E6, IsPacked = true }, + new PackedEntry { Name = "Qui2.bmp", Type = "image", Offset = 0x1422136, UnpackedSize = 0x1686, Size = 0x5E6, IsPacked = true }, + new PackedEntry { Name = "Re.bmp", Type = "image", Offset = 0x142271C, UnpackedSize = 0x1096, Size = 0x593, IsPacked = true }, + new PackedEntry { Name = "Re2.bmp", Type = "image", Offset = 0x1422CAF, UnpackedSize = 0x1096, Size = 0x593, IsPacked = true }, + new PackedEntry { Name = "Sou.bmp", Type = "image", Offset = 0x1423242, UnpackedSize = 0x13AE, Size = 0x611, IsPacked = true }, + new PackedEntry { Name = "Vo.bmp", Type = "image", Offset = 0x1423853, UnpackedSize = 0x117E, Size = 0x5B5, IsPacked = true }, + } + }, + { + "ALLXXX.273", new List() { + new PackedEntry { Name = "b_abel.spt", Type = "image", Offset = 0x0, UnpackedSize = 0x610, Size = 0x113, IsPacked = true }, + new PackedEntry { Name = "b_ann.spt", Type = "image", Offset = 0x113, UnpackedSize = 0x7B0, Size = 0x2E0, IsPacked = true }, + new PackedEntry { Name = "b_bal1.spt", Type = "image", Offset = 0x3F3, UnpackedSize = 0x0D0, Size = 0x8D, IsPacked = true }, + new PackedEntry { Name = "b_bal2.spt", Type = "image", Offset = 0x480, UnpackedSize = 0x0D0, Size = 0x8D, IsPacked = true }, + new PackedEntry { Name = "b_bat.spt", Type = "image", Offset = 0x50D, UnpackedSize = 0x0D0, Size = 0x62, IsPacked = true }, + new PackedEntry { Name = "b_bat2.spt", Type = "image", Offset = 0x56F, UnpackedSize = 0x0D0, Size = 0x5F, IsPacked = true }, + new PackedEntry { Name = "b_bee1.spt", Type = "image", Offset = 0x5CE, UnpackedSize = 0x0C0, Size = 0x61, IsPacked = true }, + new PackedEntry { Name = "b_bobe.spt", Type = "image", Offset = 0x62F, UnpackedSize = 0x0F0, Size = 0x66, IsPacked = true }, + new PackedEntry { Name = "b_bosc.spt", Type = "image", Offset = 0x695, UnpackedSize = 0x0E0, Size = 0x6C, IsPacked = true }, + new PackedEntry { Name = "b_cain.spt", Type = "image", Offset = 0x701, UnpackedSize = 0x8A0, Size = 0x2AC, IsPacked = true }, + new PackedEntry { Name = "b_chia.spt", Type = "image", Offset = 0x9AD, UnpackedSize = 0x150, Size = 0x0EB, IsPacked = true }, + new PackedEntry { Name = "b_chib.spt", Type = "image", Offset = 0x0A98, UnpackedSize = 0x150, Size = 0x0EB, IsPacked = true }, + new PackedEntry { Name = "b_chic.spt", Type = "image", Offset = 0x0B83, UnpackedSize = 0x130, Size = 0x84, IsPacked = true }, + new PackedEntry { Name = "b_clim.spt", Type = "image", Offset = 0x0C07, UnpackedSize = 0x450, Size = 0x1BF, IsPacked = true }, + new PackedEntry { Name = "b_cur1.spt", Type = "image", Offset = 0x0DC6, UnpackedSize = 0x50, Size = 0x1C, IsPacked = true }, + new PackedEntry { Name = "b_cur2.spt", Type = "image", Offset = 0x0DE2, UnpackedSize = 0x90, Size = 0x5F, IsPacked = true }, + new PackedEntry { Name = "b_dem1.spt", Type = "image", Offset = 0x0E41, UnpackedSize = 0x0C0, Size = 0x57, IsPacked = true }, + new PackedEntry { Name = "b_dem2.spt", Type = "image", Offset = 0x0E98, UnpackedSize = 0x0C0, Size = 0x57, IsPacked = true }, + new PackedEntry { Name = "b_dog.spt", Type = "image", Offset = 0x0EEF, UnpackedSize = 0x100, Size = 0x6C, IsPacked = true }, + new PackedEntry { Name = "b_dog2.spt", Type = "image", Offset = 0x0F5B, UnpackedSize = 0x140, Size = 0x0B6, IsPacked = true }, + new PackedEntry { Name = "b_dog3.spt", Type = "image", Offset = 0x1011, UnpackedSize = 0x160, Size = 0x0B0, IsPacked = true }, + new PackedEntry { Name = "b_ga1a.spt", Type = "image", Offset = 0x10C1, UnpackedSize = 0x80, Size = 0x4D, IsPacked = true }, + new PackedEntry { Name = "b_ga1b.spt", Type = "image", Offset = 0x110E, UnpackedSize = 0x0D0, Size = 0x88, IsPacked = true }, + new PackedEntry { Name = "b_ga2a.spt", Type = "image", Offset = 0x1196, UnpackedSize = 0x80, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "b_ga2b.spt", Type = "image", Offset = 0x11E4, UnpackedSize = 0x0E0, Size = 0x92, IsPacked = true }, + new PackedEntry { Name = "b_han2.spt", Type = "image", Offset = 0x1276, UnpackedSize = 0x160, Size = 0x92, IsPacked = true }, + new PackedEntry { Name = "b_hang.spt", Type = "image", Offset = 0x1308, UnpackedSize = 0x160, Size = 0x92, IsPacked = true }, + new PackedEntry { Name = "b_har2.spt", Type = "image", Offset = 0x139A, UnpackedSize = 0x0E0, Size = 0x0A3, IsPacked = true }, + new PackedEntry { Name = "b_harp.spt", Type = "image", Offset = 0x143D, UnpackedSize = 0x0E0, Size = 0x0A3, IsPacked = true }, + new PackedEntry { Name = "b_hebi.spt", Type = "image", Offset = 0x14E0, UnpackedSize = 0x150, Size = 0x64, IsPacked = true }, + new PackedEntry { Name = "b_hei1.spt", Type = "image", Offset = 0x1544, UnpackedSize = 0x0C0, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "b_hei2.spt", Type = "image", Offset = 0x1592, UnpackedSize = 0x0D0, Size = 0x6B, IsPacked = true }, + new PackedEntry { Name = "b_hei3.spt", Type = "image", Offset = 0x15FD, UnpackedSize = 0x0E0, Size = 0x76, IsPacked = true }, + new PackedEntry { Name = "b_jia2.spt", Type = "image", Offset = 0x1673, UnpackedSize = 0x0B0, Size = 0x68, IsPacked = true }, + new PackedEntry { Name = "b_jia3.spt", Type = "image", Offset = 0x16DB, UnpackedSize = 0x0B0, Size = 0x6B, IsPacked = true }, + new PackedEntry { Name = "b_jia4.spt", Type = "image", Offset = 0x1746, UnpackedSize = 0x0B0, Size = 0x69, IsPacked = true }, + new PackedEntry { Name = "b_jian.spt", Type = "image", Offset = 0x17AF, UnpackedSize = 0x0E0, Size = 0x0A5, IsPacked = true }, + new PackedEntry { Name = "b_kasi.spt", Type = "image", Offset = 0x1854, UnpackedSize = 0x100, Size = 0x89, IsPacked = true }, + new PackedEntry { Name = "b_kim2.spt", Type = "image", Offset = 0x18DD, UnpackedSize = 0x0B0, Size = 0x7D, IsPacked = true }, + new PackedEntry { Name = "b_kime.spt", Type = "image", Offset = 0x195A, UnpackedSize = 0x0D0, Size = 0x89, IsPacked = true }, + new PackedEntry { Name = "b_kin1.spt", Type = "image", Offset = 0x19E3, UnpackedSize = 0x250, Size = 0x99, IsPacked = true }, + new PackedEntry { Name = "b_kin2.spt", Type = "image", Offset = 0x1A7C, UnpackedSize = 0x0B0, Size = 0x44, IsPacked = true }, + new PackedEntry { Name = "b_kin3.spt", Type = "image", Offset = 0x1AC0, UnpackedSize = 0x50, Size = 0x2D, IsPacked = true }, + new PackedEntry { Name = "b_kob2.spt", Type = "image", Offset = 0x1AED, UnpackedSize = 0x0B0, Size = 0x68, IsPacked = true }, + new PackedEntry { Name = "b_kobo.spt", Type = "image", Offset = 0x1B55, UnpackedSize = 0x0B0, Size = 0x67, IsPacked = true }, + new PackedEntry { Name = "b_mac1.spt", Type = "image", Offset = 0x1BBC, UnpackedSize = 0x80, Size = 0x54, IsPacked = true }, + new PackedEntry { Name = "b_mac2.spt", Type = "image", Offset = 0x1C10, UnpackedSize = 0x0A0, Size = 0x64, IsPacked = true }, + new PackedEntry { Name = "b_mac3.spt", Type = "image", Offset = 0x1C74, UnpackedSize = 0x0B0, Size = 0x7A, IsPacked = true }, + new PackedEntry { Name = "b_maj1.spt", Type = "image", Offset = 0x1CEE, UnpackedSize = 0x90, Size = 0x47, IsPacked = true }, + new PackedEntry { Name = "b_maj2.spt", Type = "image", Offset = 0x1D35, UnpackedSize = 0x90, Size = 0x47, IsPacked = true }, + new PackedEntry { Name = "b_maj3.spt", Type = "image", Offset = 0x1D7C, UnpackedSize = 0x90, Size = 0x48, IsPacked = true }, + new PackedEntry { Name = "b_pon.spt", Type = "image", Offset = 0x1DC4, UnpackedSize = 0x430, Size = 0x278, IsPacked = true }, + new PackedEntry { Name = "b_riq.spt", Type = "image", Offset = 0x203C, UnpackedSize = 0x440, Size = 0x264, IsPacked = true }, + new PackedEntry { Name = "b_rob1.spt", Type = "image", Offset = 0x22A0, UnpackedSize = 0x1B0, Size = 0x0B8, IsPacked = true }, + new PackedEntry { Name = "b_rob2.spt", Type = "image", Offset = 0x2358, UnpackedSize = 0x1B0, Size = 0x0B7, IsPacked = true }, + new PackedEntry { Name = "b_russ.spt", Type = "image", Offset = 0x240F, UnpackedSize = 0x790, Size = 0x263, IsPacked = true }, + new PackedEntry { Name = "b_sab1.spt", Type = "image", Offset = 0x2672, UnpackedSize = 0x1A0, Size = 0x0E4, IsPacked = true }, + new PackedEntry { Name = "b_sab2.spt", Type = "image", Offset = 0x2756, UnpackedSize = 0x130, Size = 0x95, IsPacked = true }, + new PackedEntry { Name = "b_sem2.spt", Type = "image", Offset = 0x27EB, UnpackedSize = 0x0D0, Size = 0x8F, IsPacked = true }, + new PackedEntry { Name = "b_semu.spt", Type = "image", Offset = 0x287A, UnpackedSize = 0x0D0, Size = 0x7B, IsPacked = true }, + new PackedEntry { Name = "b_ska2.spt", Type = "image", Offset = 0x28F5, UnpackedSize = 0x160, Size = 0x0A4, IsPacked = true }, + new PackedEntry { Name = "b_ska3.spt", Type = "image", Offset = 0x2999, UnpackedSize = 0x160, Size = 0x0A4, IsPacked = true }, + new PackedEntry { Name = "b_skal.spt", Type = "image", Offset = 0x2A3D, UnpackedSize = 0x0C0, Size = 0x72, IsPacked = true }, + new PackedEntry { Name = "b_sur2.spt", Type = "image", Offset = 0x2AAF, UnpackedSize = 0x100, Size = 0x7B, IsPacked = true }, + new PackedEntry { Name = "b_sur3.spt", Type = "image", Offset = 0x2B2A, UnpackedSize = 0x100, Size = 0x7B, IsPacked = true }, + new PackedEntry { Name = "b_sura.spt", Type = "image", Offset = 0x2BA5, UnpackedSize = 0x100, Size = 0x77, IsPacked = true }, + new PackedEntry { Name = "b_sys.spt", Type = "image", Offset = 0x2C1C, UnpackedSize = 0x0F0, Size = 0x59, IsPacked = true }, + new PackedEntry { Name = "b_thi1.spt", Type = "image", Offset = 0x2C75, UnpackedSize = 0x0C0, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "b_thi2.spt", Type = "image", Offset = 0x2CC3, UnpackedSize = 0x0C0, Size = 0x70, IsPacked = true }, + new PackedEntry { Name = "b_tira.spt", Type = "image", Offset = 0x2D33, UnpackedSize = 0x1B0, Size = 0x0EB, IsPacked = true }, + new PackedEntry { Name = "b_tora.spt", Type = "image", Offset = 0x2E1E, UnpackedSize = 0x130, Size = 0x0A7, IsPacked = true }, + new PackedEntry { Name = "b_tre2.spt", Type = "image", Offset = 0x2EC5, UnpackedSize = 0x100, Size = 0x88, IsPacked = true }, + new PackedEntry { Name = "b_tree.spt", Type = "image", Offset = 0x2F4D, UnpackedSize = 0x100, Size = 0x87, IsPacked = true }, + new PackedEntry { Name = "b_uma1.spt", Type = "image", Offset = 0x2FD4, UnpackedSize = 0x0E0, Size = 0x81, IsPacked = true }, + new PackedEntry { Name = "b_uma2.spt", Type = "image", Offset = 0x3055, UnpackedSize = 0x0E0, Size = 0x81, IsPacked = true }, + new PackedEntry { Name = "b_was2.spt", Type = "image", Offset = 0x30D6, UnpackedSize = 0x120, Size = 0x0B9, IsPacked = true }, + new PackedEntry { Name = "b_wasi.spt", Type = "image", Offset = 0x318F, UnpackedSize = 0x120, Size = 0x0B6, IsPacked = true }, + new PackedEntry { Name = "b_wiz1.spt", Type = "image", Offset = 0x3245, UnpackedSize = 0x120, Size = 0x5C, IsPacked = true }, + new PackedEntry { Name = "b_wiz2.spt", Type = "image", Offset = 0x32A1, UnpackedSize = 0x0C0, Size = 0x4F, IsPacked = true }, + new PackedEntry { Name = "b_yaj2.spt", Type = "image", Offset = 0x32F0, UnpackedSize = 0x0C0, Size = 0x72, IsPacked = true }, + new PackedEntry { Name = "b_yaj3.spt", Type = "image", Offset = 0x3362, UnpackedSize = 0x0D0, Size = 0x98, IsPacked = true }, + new PackedEntry { Name = "b_yaji.spt", Type = "image", Offset = 0x33FA, UnpackedSize = 0x0D0, Size = 0x98, IsPacked = true }, + new PackedEntry { Name = "b_zom1.spt", Type = "image", Offset = 0x3492, UnpackedSize = 0x0E0, Size = 0x8E, IsPacked = true }, + new PackedEntry { Name = "b_zom2.spt", Type = "image", Offset = 0x3520, UnpackedSize = 0x0E0, Size = 0x8E, IsPacked = true }, + new PackedEntry { Name = "allmap.cod", Type = "image", Offset = 0x35AE, UnpackedSize = 0x5D58, Size = 0x2C61, IsPacked = true }, + new PackedEntry { Name = "badend.cod", Type = "image", Offset = 0x620F, UnpackedSize = 0x0C06, Size = 0x6F7, IsPacked = true }, + new PackedEntry { Name = "cgm_anni.cod", Type = "image", Offset = 0x6906, UnpackedSize = 0x5B4, Size = 0x26C, IsPacked = true }, + new PackedEntry { Name = "cgm_crim.cod", Type = "image", Offset = 0x6B72, UnpackedSize = 0x58E, Size = 0x26E, IsPacked = true }, + new PackedEntry { Name = "cgm_gana.cod", Type = "image", Offset = 0x6DE0, UnpackedSize = 0x4D4, Size = 0x231, IsPacked = true }, + new PackedEntry { Name = "cgm_king.cod", Type = "image", Offset = 0x7011, UnpackedSize = 0x30A, Size = 0x1AE, IsPacked = true }, + new PackedEntry { Name = "cgm_mafi.cod", Type = "image", Offset = 0x71BF, UnpackedSize = 0x63C, Size = 0x26C, IsPacked = true }, + new PackedEntry { Name = "cgm_milf.cod", Type = "image", Offset = 0x742B, UnpackedSize = 0x488, Size = 0x226, IsPacked = true }, + new PackedEntry { Name = "cgm_pann.cod", Type = "image", Offset = 0x7651, UnpackedSize = 0x3FC, Size = 0x205, IsPacked = true }, + new PackedEntry { Name = "cgm_quee.cod", Type = "image", Offset = 0x7856, UnpackedSize = 0x468, Size = 0x242, IsPacked = true }, + new PackedEntry { Name = "cgm_riqu.cod", Type = "image", Offset = 0x7A98, UnpackedSize = 0x5A0, Size = 0x264, IsPacked = true }, + new PackedEntry { Name = "cgm_ruse.cod", Type = "image", Offset = 0x7CFC, UnpackedSize = 0x58E, Size = 0x247, IsPacked = true }, + new PackedEntry { Name = "cgm_seli.cod", Type = "image", Offset = 0x7F43, UnpackedSize = 0x582, Size = 0x24A, IsPacked = true }, + new PackedEntry { Name = "cgm_shak.cod", Type = "image", Offset = 0x818D, UnpackedSize = 0x42A, Size = 0x244, IsPacked = true }, + new PackedEntry { Name = "cgm_shok.cod", Type = "image", Offset = 0x83D1, UnpackedSize = 0x5D0, Size = 0x288, IsPacked = true }, + new PackedEntry { Name = "cgm_shuk.cod", Type = "image", Offset = 0x8659, UnpackedSize = 0x40E, Size = 0x1EA, IsPacked = true }, + new PackedEntry { Name = "cgm_tira.cod", Type = "image", Offset = 0x8843, UnpackedSize = 0x3D0, Size = 0x1E2, IsPacked = true }, + new PackedEntry { Name = "cgm_tolt.cod", Type = "image", Offset = 0x8A25, UnpackedSize = 0x58E, Size = 0x269, IsPacked = true }, + new PackedEntry { Name = "cron.cod", Type = "image", Offset = 0x8C8E, UnpackedSize = 0x309E, Size = 0x1807, IsPacked = true }, + new PackedEntry { Name = "cudu.cod", Type = "image", Offset = 0x0A495, UnpackedSize = 0x0FD0, Size = 0x6C0, IsPacked = true }, + new PackedEntry { Name = "dragon.cod", Type = "image", Offset = 0x0AB55, UnpackedSize = 0x55C8, Size = 0x29AA, IsPacked = true }, + new PackedEntry { Name = "ending.cod", Type = "image", Offset = 0x0D4FF, UnpackedSize = 0x0DE88, Size = 0x69F2, IsPacked = true }, + new PackedEntry { Name = "endsyoko.cod", Type = "image", Offset = 0x13EF1, UnpackedSize = 0x535C, Size = 0x2872, IsPacked = true }, + new PackedEntry { Name = "flap.cod", Type = "image", Offset = 0x16763, UnpackedSize = 0x0C6F0, Size = 0x595D, IsPacked = true }, + new PackedEntry { Name = "fond.cod", Type = "image", Offset = 0x1C0C0, UnpackedSize = 0x0BB0, Size = 0x4F3, IsPacked = true }, + new PackedEntry { Name = "garu.cod", Type = "image", Offset = 0x1C5B3, UnpackedSize = 0x0E06, Size = 0x5E2, IsPacked = true }, + new PackedEntry { Name = "ikki.cod", Type = "image", Offset = 0x1CB95, UnpackedSize = 0x56F8, Size = 0x2541, IsPacked = true }, + new PackedEntry { Name = "intro.cod", Type = "image", Offset = 0x1F0D6, UnpackedSize = 0x607C, Size = 0x2DE1, IsPacked = true }, + new PackedEntry { Name = "iseki.cod", Type = "image", Offset = 0x21EB7, UnpackedSize = 0x470E, Size = 0x20FF, IsPacked = true }, + new PackedEntry { Name = "joka.cod", Type = "image", Offset = 0x23FB6, UnpackedSize = 0x8BE8, Size = 0x424E, IsPacked = true }, + new PackedEntry { Name = "jokaann.cod", Type = "image", Offset = 0x28204, UnpackedSize = 0x2884, Size = 0x145A, IsPacked = true }, + new PackedEntry { Name = "jokamaf.cod", Type = "image", Offset = 0x2965E, UnpackedSize = 0x0AF66, Size = 0x5001, IsPacked = true }, + new PackedEntry { Name = "kaiz.cod", Type = "image", Offset = 0x2E65F, UnpackedSize = 0x1B40, Size = 0x0C7F, IsPacked = true }, + new PackedEntry { Name = "kata.cod", Type = "image", Offset = 0x2F2DE, UnpackedSize = 0x0BF30, Size = 0x5935, IsPacked = true }, + new PackedEntry { Name = "koro.cod", Type = "image", Offset = 0x34C13, UnpackedSize = 0x80E4, Size = 0x3D6F, IsPacked = true }, + new PackedEntry { Name = "kuro.cod", Type = "image", Offset = 0x38982, UnpackedSize = 0x4294, Size = 0x1F42, IsPacked = true }, + new PackedEntry { Name = "last.cod", Type = "image", Offset = 0x3A8C4, UnpackedSize = 0x4DAC, Size = 0x23F9, IsPacked = true }, + new PackedEntry { Name = "matuclim.cod", Type = "image", Offset = 0x3CCBD, UnpackedSize = 0x49E0, Size = 0x2187, IsPacked = true }, + new PackedEntry { Name = "mura.cod", Type = "image", Offset = 0x3EE44, UnpackedSize = 0x6426, Size = 0x2F6F, IsPacked = true }, + new PackedEntry { Name = "ojou.cod", Type = "image", Offset = 0x41DB3, UnpackedSize = 0x0E032, Size = 0x6248, IsPacked = true }, + new PackedEntry { Name = "oldw.cod", Type = "image", Offset = 0x47FFB, UnpackedSize = 0x4E7E, Size = 0x265A, IsPacked = true }, + new PackedEntry { Name = "pare.cod", Type = "image", Offset = 0x4A655, UnpackedSize = 0x0E4FE, Size = 0x6984, IsPacked = true }, + new PackedEntry { Name = "quick.cod", Type = "image", Offset = 0x50FD9, UnpackedSize = 0x10, Size = 0x14, IsPacked = true }, + new PackedEntry { Name = "retry.cod", Type = "image", Offset = 0x50FED, UnpackedSize = 0x4E, Size = 0x52, IsPacked = true }, + new PackedEntry { Name = "saba.cod", Type = "image", Offset = 0x5103F, UnpackedSize = 0x9CA, Size = 0x326, IsPacked = true }, + new PackedEntry { Name = "selijoka.cod", Type = "image", Offset = 0x51365, UnpackedSize = 0x2D64, Size = 0x162F, IsPacked = true }, + new PackedEntry { Name = "sepu.cod", Type = "image", Offset = 0x52994, UnpackedSize = 0x0A468, Size = 0x481B, IsPacked = true }, + new PackedEntry { Name = "shikei.cod", Type = "image", Offset = 0x571AF, UnpackedSize = 0x2FA8, Size = 0x185F, IsPacked = true }, + new PackedEntry { Name = "sima.cod", Type = "image", Offset = 0x58A0E, UnpackedSize = 0x958, Size = 0x390, IsPacked = true }, + new PackedEntry { Name = "start.cod", Type = "image", Offset = 0x58D9E, UnpackedSize = 0x10, Size = 0x14, IsPacked = true }, + new PackedEntry { Name = "syud.cod", Type = "image", Offset = 0x58DB2, UnpackedSize = 0x6F4A, Size = 0x3353, IsPacked = true }, + new PackedEntry { Name = "test.cod", Type = "image", Offset = 0x5C105, UnpackedSize = 0x26, Size = 0x22, IsPacked = true }, + new PackedEntry { Name = "tidu.cod", Type = "image", Offset = 0x5C127, UnpackedSize = 0x5FDA, Size = 0x2CA3, IsPacked = true }, + new PackedEntry { Name = "tita.cod", Type = "image", Offset = 0x5EDCA, UnpackedSize = 0x940, Size = 0x37E, IsPacked = true }, + new PackedEntry { Name = "tori.cod", Type = "image", Offset = 0x5F148, UnpackedSize = 0x0E3C2, Size = 0x6455, IsPacked = true }, + new PackedEntry { Name = "umaya.cod", Type = "image", Offset = 0x6559D, UnpackedSize = 0x52A8, Size = 0x2832, IsPacked = true }, + new PackedEntry { Name = "yama.cod", Type = "image", Offset = 0x67DCF, UnpackedSize = 0x1282, Size = 0x757, IsPacked = true }, + new PackedEntry { Name = "yuru.cod", Type = "image", Offset = 0x68526, UnpackedSize = 0x0F48C, Size = 0x7274, IsPacked = true }, + new PackedEntry { Name = "ankei_a.sp2", Type = "image", Offset = 0x6F79A, UnpackedSize = 0x143, Size = 0x147, IsPacked = true }, + new PackedEntry { Name = "ankei_b.sp2", Type = "image", Offset = 0x6F8E1, UnpackedSize = 0x10D, Size = 0x111, IsPacked = true }, + new PackedEntry { Name = "ankei_c.sp2", Type = "image", Offset = 0x6F9F2, UnpackedSize = 0x143, Size = 0x147, IsPacked = true }, + new PackedEntry { Name = "beem_a.sp2", Type = "image", Offset = 0x6FB39, UnpackedSize = 0x413, Size = 0x356, IsPacked = true }, + new PackedEntry { Name = "beem_b.sp2", Type = "image", Offset = 0x6FE8F, UnpackedSize = 0x38F, Size = 0x2EC, IsPacked = true }, + new PackedEntry { Name = "beem_c.sp2", Type = "image", Offset = 0x7017B, UnpackedSize = 0x446, Size = 0x382, IsPacked = true }, + new PackedEntry { Name = "b_abel_a.sp2", Type = "image", Offset = 0x704FD, UnpackedSize = 0x1136, Size = 0x0DF1, IsPacked = true }, + new PackedEntry { Name = "b_ann_a.sp2", Type = "image", Offset = 0x712EE, UnpackedSize = 0x25D9, Size = 0x1DA6, IsPacked = true }, + new PackedEntry { Name = "b_ann_b.sp2", Type = "image", Offset = 0x73094, UnpackedSize = 0x251F, Size = 0x1BFD, IsPacked = true }, + new PackedEntry { Name = "b_ann_c.sp2", Type = "image", Offset = 0x74C91, UnpackedSize = 0x2543, Size = 0x1C14, IsPacked = true }, + new PackedEntry { Name = "b_bal1_a.sp2", Type = "image", Offset = 0x768A5, UnpackedSize = 0x1AF0, Size = 0x0AD5, IsPacked = true }, + new PackedEntry { Name = "b_bat_a.sp2", Type = "image", Offset = 0x7737A, UnpackedSize = 0x8D8, Size = 0x5CF, IsPacked = true }, + new PackedEntry { Name = "b_bat_b.sp2", Type = "image", Offset = 0x77949, UnpackedSize = 0x8D8, Size = 0x5DC, IsPacked = true }, + new PackedEntry { Name = "b_bee1_a.sp2", Type = "image", Offset = 0x77F25, UnpackedSize = 0x0D04, Size = 0x0ADF, IsPacked = true }, + new PackedEntry { Name = "b_bobe_a.sp2", Type = "image", Offset = 0x78A04, UnpackedSize = 0x6D1, Size = 0x5C6, IsPacked = true }, + new PackedEntry { Name = "b_bosc_a.sp2", Type = "image", Offset = 0x78FCA, UnpackedSize = 0x48E, Size = 0x3F8, IsPacked = true }, + new PackedEntry { Name = "b_cain_a.sp2", Type = "image", Offset = 0x793C2, UnpackedSize = 0x1C4F, Size = 0x16E7, IsPacked = true }, + new PackedEntry { Name = "b_cain_b.sp2", Type = "image", Offset = 0x7AAA9, UnpackedSize = 0x1D00, Size = 0x17AE, IsPacked = true }, + new PackedEntry { Name = "b_cain_c.sp2", Type = "image", Offset = 0x7C257, UnpackedSize = 0x1AFC, Size = 0x1611, IsPacked = true }, + new PackedEntry { Name = "b_chia_a.sp2", Type = "image", Offset = 0x7D868, UnpackedSize = 0x17CC, Size = 0x0F99, IsPacked = true }, + new PackedEntry { Name = "b_chib_a.sp2", Type = "image", Offset = 0x7E801, UnpackedSize = 0x17AB, Size = 0x0FDD, IsPacked = true }, + new PackedEntry { Name = "b_chic_a.sp2", Type = "image", Offset = 0x7F7DE, UnpackedSize = 0x1358, Size = 0x64A, IsPacked = true }, + new PackedEntry { Name = "b_clim_a.sp2", Type = "image", Offset = 0x7FE28, UnpackedSize = 0x0C59, Size = 0x729, IsPacked = true }, + new PackedEntry { Name = "b_clim_b.sp2", Type = "image", Offset = 0x80551, UnpackedSize = 0x0CE3, Size = 0x7F8, IsPacked = true }, + new PackedEntry { Name = "b_clim_c.sp2", Type = "image", Offset = 0x80D49, UnpackedSize = 0x0A52, Size = 0x6CE, IsPacked = true }, + new PackedEntry { Name = "b_cur1_a.sp2", Type = "image", Offset = 0x81417, UnpackedSize = 0x85D, Size = 0x306, IsPacked = true }, + new PackedEntry { Name = "b_cur2_a.sp2", Type = "image", Offset = 0x8171D, UnpackedSize = 0x212F, Size = 0x0CCE, IsPacked = true }, + new PackedEntry { Name = "b_dem1_a.sp2", Type = "image", Offset = 0x823EB, UnpackedSize = 0x8AE, Size = 0x8B2, IsPacked = true }, + new PackedEntry { Name = "b_dem1_b.sp2", Type = "image", Offset = 0x82C9D, UnpackedSize = 0x8FC, Size = 0x900, IsPacked = true }, + new PackedEntry { Name = "b_dog_b.sp2", Type = "image", Offset = 0x8359D, UnpackedSize = 0x1589, Size = 0x0FDE, IsPacked = true }, + new PackedEntry { Name = "b_ga1a_b.sp2", Type = "image", Offset = 0x8457B, UnpackedSize = 0x156B, Size = 0x529, IsPacked = true }, + new PackedEntry { Name = "b_ga1b_b.sp2", Type = "image", Offset = 0x84AA4, UnpackedSize = 0x25F4, Size = 0x0D3D, IsPacked = true }, + new PackedEntry { Name = "b_ga2a_a.sp2", Type = "image", Offset = 0x857E1, UnpackedSize = 0x0C7D, Size = 0x381, IsPacked = true }, + new PackedEntry { Name = "b_ga2b_a.sp2", Type = "image", Offset = 0x85B62, UnpackedSize = 0x38F3, Size = 0x0E90, IsPacked = true }, + new PackedEntry { Name = "b_hang_a.sp2", Type = "image", Offset = 0x869F2, UnpackedSize = 0x1790, Size = 0x1341, IsPacked = true }, + new PackedEntry { Name = "b_harp_a.sp2", Type = "image", Offset = 0x87D33, UnpackedSize = 0x1BAA, Size = 0x0B67, IsPacked = true }, + new PackedEntry { Name = "b_harp_b.sp2", Type = "image", Offset = 0x8889A, UnpackedSize = 0x1B80, Size = 0x0B09, IsPacked = true }, + new PackedEntry { Name = "b_hebi_a.sp2", Type = "image", Offset = 0x893A3, UnpackedSize = 0x0F98, Size = 0x0DF4, IsPacked = true }, + new PackedEntry { Name = "b_hei1_a.sp2", Type = "image", Offset = 0x8A197, UnpackedSize = 0x1667, Size = 0x0D77, IsPacked = true }, + new PackedEntry { Name = "b_icon.sp2", Type = "image", Offset = 0x8AF0E, UnpackedSize = 0x3E9, Size = 0x34E, IsPacked = true }, + new PackedEntry { Name = "b_iconb.sp2", Type = "image", Offset = 0x8B25C, UnpackedSize = 0x31D, Size = 0x14C, IsPacked = true }, + new PackedEntry { Name = "b_jian_b.sp2", Type = "image", Offset = 0x8B3A8, UnpackedSize = 0x386C, Size = 0x1B31, IsPacked = true }, + new PackedEntry { Name = "b_kasi_a.sp2", Type = "image", Offset = 0x8CED9, UnpackedSize = 0x1604, Size = 0x0C18, IsPacked = true }, + new PackedEntry { Name = "b_kime_b.sp2", Type = "image", Offset = 0x8DAF1, UnpackedSize = 0x1E65, Size = 0x0FAF, IsPacked = true }, + new PackedEntry { Name = "b_kin1_a.sp2", Type = "image", Offset = 0x8EAA0, UnpackedSize = 0x5855, Size = 0x14C3, IsPacked = true }, + new PackedEntry { Name = "b_kin2_a.sp2", Type = "image", Offset = 0x8FF63, UnpackedSize = 0x0EED, Size = 0x0C2B, IsPacked = true }, + new PackedEntry { Name = "b_kin3_a.sp2", Type = "image", Offset = 0x90B8E, UnpackedSize = 0x20D2, Size = 0x1A9C, IsPacked = true }, + new PackedEntry { Name = "b_kobo_a.sp2", Type = "image", Offset = 0x9262A, UnpackedSize = 0x848, Size = 0x53A, IsPacked = true }, + new PackedEntry { Name = "b_kobo_b.sp2", Type = "image", Offset = 0x92B64, UnpackedSize = 0x7A6, Size = 0x4C5, IsPacked = true }, + new PackedEntry { Name = "b_kobo_c.sp2", Type = "image", Offset = 0x93029, UnpackedSize = 0x6FE, Size = 0x452, IsPacked = true }, + new PackedEntry { Name = "b_mac1_b.sp2", Type = "image", Offset = 0x9347B, UnpackedSize = 0x6C8, Size = 0x1B6, IsPacked = true }, + new PackedEntry { Name = "b_mac2_b.sp2", Type = "image", Offset = 0x93631, UnpackedSize = 0x0AC7, Size = 0x2EB, IsPacked = true }, + new PackedEntry { Name = "b_mac3_b.sp2", Type = "image", Offset = 0x9391C, UnpackedSize = 0x6D70, Size = 0x13CC, IsPacked = true }, + new PackedEntry { Name = "b_magic0.sp2", Type = "image", Offset = 0x94CE8, UnpackedSize = 0x1EB, Size = 0x1EF, IsPacked = true }, + new PackedEntry { Name = "b_magic1.sp2", Type = "image", Offset = 0x94ED7, UnpackedSize = 0x3CB, Size = 0x3CF, IsPacked = true }, + new PackedEntry { Name = "b_magic2.sp2", Type = "image", Offset = 0x952A6, UnpackedSize = 0x0C5, Size = 0x94, IsPacked = true }, + new PackedEntry { Name = "b_magic3.sp2", Type = "image", Offset = 0x9533A, UnpackedSize = 0x56, Size = 0x5A, IsPacked = true }, + new PackedEntry { Name = "b_magic4.sp2", Type = "image", Offset = 0x95394, UnpackedSize = 0x1CA, Size = 0x1CE, IsPacked = true }, + new PackedEntry { Name = "b_magic5.sp2", Type = "image", Offset = 0x95562, UnpackedSize = 0x8C0, Size = 0x8C4, IsPacked = true }, + new PackedEntry { Name = "b_magic6.sp2", Type = "image", Offset = 0x95E26, UnpackedSize = 0x8C0, Size = 0x8C4, IsPacked = true }, + new PackedEntry { Name = "b_magic7.sp2", Type = "image", Offset = 0x966EA, UnpackedSize = 0x54E, Size = 0x552, IsPacked = true }, + new PackedEntry { Name = "b_magic8.sp2", Type = "image", Offset = 0x96C3C, UnpackedSize = 0x428, Size = 0x42C, IsPacked = true }, + new PackedEntry { Name = "b_maj1_a.sp2", Type = "image", Offset = 0x97068, UnpackedSize = 0x740, Size = 0x516, IsPacked = true }, + new PackedEntry { Name = "b_pon_a.sp2", Type = "image", Offset = 0x9757E, UnpackedSize = 0x10FA, Size = 0x0D3D, IsPacked = true }, + new PackedEntry { Name = "b_pon_b.sp2", Type = "image", Offset = 0x982BB, UnpackedSize = 0x0FE6, Size = 0x0BD1, IsPacked = true }, + new PackedEntry { Name = "b_pon_c.sp2", Type = "image", Offset = 0x98E8C, UnpackedSize = 0x10F7, Size = 0x0CE1, IsPacked = true }, + new PackedEntry { Name = "b_riq_a.sp2", Type = "image", Offset = 0x99B6D, UnpackedSize = 0x102B, Size = 0x0A2A, IsPacked = true }, + new PackedEntry { Name = "b_riq_b.sp2", Type = "image", Offset = 0x9A597, UnpackedSize = 0x104C, Size = 0x0A1D, IsPacked = true }, + new PackedEntry { Name = "b_riq_c.sp2", Type = "image", Offset = 0x9AFB4, UnpackedSize = 0x0F9E, Size = 0x981, IsPacked = true }, + new PackedEntry { Name = "b_rob1_a.sp2", Type = "image", Offset = 0x9B935, UnpackedSize = 0x6F26, Size = 0x218F, IsPacked = true }, + new PackedEntry { Name = "b_russ_a.sp2", Type = "image", Offset = 0x9DAC4, UnpackedSize = 0x17F6, Size = 0x0FEB, IsPacked = true }, + new PackedEntry { Name = "b_russ_b.sp2", Type = "image", Offset = 0x9EAAF, UnpackedSize = 0x1838, Size = 0x0F20, IsPacked = true }, + new PackedEntry { Name = "b_russ_c.sp2", Type = "image", Offset = 0x9F9CF, UnpackedSize = 0x16C4, Size = 0x0E23, IsPacked = true }, + new PackedEntry { Name = "b_sab1_a.sp2", Type = "image", Offset = 0x0A07F2, UnpackedSize = 0x407F, Size = 0x1ABE, IsPacked = true }, + new PackedEntry { Name = "b_semu_b.sp2", Type = "image", Offset = 0x0A22B0, UnpackedSize = 0x1B08, Size = 0x1108, IsPacked = true }, + new PackedEntry { Name = "b_skal_a.sp2", Type = "image", Offset = 0x0A33B8, UnpackedSize = 0x1073, Size = 0x0BE5, IsPacked = true }, + new PackedEntry { Name = "b_skal_b.sp2", Type = "image", Offset = 0x0A3F9D, UnpackedSize = 0x101F, Size = 0x0BC7, IsPacked = true }, + new PackedEntry { Name = "b_skal_c.sp2", Type = "image", Offset = 0x0A4B64, UnpackedSize = 0x1013, Size = 0x0B59, IsPacked = true }, + new PackedEntry { Name = "b_sura_a.sp2", Type = "image", Offset = 0x0A56BD, UnpackedSize = 0x596, Size = 0x442, IsPacked = true }, + new PackedEntry { Name = "b_sura_b.sp2", Type = "image", Offset = 0x0A5AFF, UnpackedSize = 0x51E, Size = 0x417, IsPacked = true }, + new PackedEntry { Name = "b_sura_c.sp2", Type = "image", Offset = 0x0A5F16, UnpackedSize = 0x590, Size = 0x41C, IsPacked = true }, + new PackedEntry { Name = "b_sys.sp2", Type = "image", Offset = 0x0A6332, UnpackedSize = 0x28A, Size = 0x28E, IsPacked = true }, + new PackedEntry { Name = "b_sys2.sp2", Type = "image", Offset = 0x0A65C0, UnpackedSize = 0x266, Size = 0x26A, IsPacked = true }, + new PackedEntry { Name = "b_thi1_a.sp2", Type = "image", Offset = 0x0A682A, UnpackedSize = 0x0DFD, Size = 0x81E, IsPacked = true }, + new PackedEntry { Name = "b_tira_a.sp2", Type = "image", Offset = 0x0A7048, UnpackedSize = 0x1BAD, Size = 0x1040, IsPacked = true }, + new PackedEntry { Name = "b_tora_a.sp2", Type = "image", Offset = 0x0A8088, UnpackedSize = 0x19E2, Size = 0x11CC, IsPacked = true }, + new PackedEntry { Name = "b_tora_b.sp2", Type = "image", Offset = 0x0A9254, UnpackedSize = 0x1AC9, Size = 0x1078, IsPacked = true }, + new PackedEntry { Name = "b_tora_c.sp2", Type = "image", Offset = 0x0AA2CC, UnpackedSize = 0x1A54, Size = 0x10FE, IsPacked = true }, + new PackedEntry { Name = "b_tree_a.sp2", Type = "image", Offset = 0x0AB3CA, UnpackedSize = 0x2756, Size = 0x0E97, IsPacked = true }, + new PackedEntry { Name = "b_uma.sp2", Type = "image", Offset = 0x0AC261, UnpackedSize = 0x0D0D, Size = 0x0BF0, IsPacked = true }, + new PackedEntry { Name = "b_uma1_b.sp2", Type = "image", Offset = 0x0ACE51, UnpackedSize = 0x194F, Size = 0x10D7, IsPacked = true }, + new PackedEntry { Name = "b_wasi_a.sp2", Type = "image", Offset = 0x0ADF28, UnpackedSize = 0x1B29, Size = 0x10D8, IsPacked = true }, + new PackedEntry { Name = "b_wasi_b.sp2", Type = "image", Offset = 0x0AF000, UnpackedSize = 0x1B5F, Size = 0x1084, IsPacked = true }, + new PackedEntry { Name = "b_wiz1_a.sp2", Type = "image", Offset = 0x0B0084, UnpackedSize = 0x0CD1, Size = 0x0AD9, IsPacked = true }, + new PackedEntry { Name = "b_yaji_c.sp2", Type = "image", Offset = 0x0B0B5D, UnpackedSize = 0x1D81, Size = 0x1261, IsPacked = true }, + new PackedEntry { Name = "b_zom1_b.sp2", Type = "image", Offset = 0x0B1DBE, UnpackedSize = 0x0A01, Size = 0x6F3, IsPacked = true }, + new PackedEntry { Name = "con_chr.sp2", Type = "image", Offset = 0x0B24B1, UnpackedSize = 0x1E5, Size = 0x1E9, IsPacked = true }, + new PackedEntry { Name = "f_abel.sp2", Type = "image", Offset = 0x0B269A, UnpackedSize = 0x68C, Size = 0x4FC, IsPacked = true }, + new PackedEntry { Name = "f_annin.sp2", Type = "image", Offset = 0x0B2B96, UnpackedSize = 0x716, Size = 0x5B7, IsPacked = true }, + new PackedEntry { Name = "f_baba.sp2", Type = "image", Offset = 0x0B314D, UnpackedSize = 0x686, Size = 0x26B, IsPacked = true }, + new PackedEntry { Name = "f_bajil.sp2", Type = "image", Offset = 0x0B33B8, UnpackedSize = 0x6EC, Size = 0x323, IsPacked = true }, + new PackedEntry { Name = "f_baten.sp2", Type = "image", Offset = 0x0B36DB, UnpackedSize = 0x560, Size = 0x248, IsPacked = true }, + new PackedEntry { Name = "f_bobes.sp2", Type = "image", Offset = 0x0B3923, UnpackedSize = 0x869, Size = 0x6ED, IsPacked = true }, + new PackedEntry { Name = "f_bosco.sp2", Type = "image", Offset = 0x0B4010, UnpackedSize = 0x71F, Size = 0x63E, IsPacked = true }, + new PackedEntry { Name = "f_boy1.sp2", Type = "image", Offset = 0x0B464E, UnpackedSize = 0x5D8, Size = 0x418, IsPacked = true }, + new PackedEntry { Name = "f_buki.sp2", Type = "image", Offset = 0x0B4A66, UnpackedSize = 0x61A, Size = 0x28A, IsPacked = true }, + new PackedEntry { Name = "f_cain.sp2", Type = "image", Offset = 0x0B4CF0, UnpackedSize = 0x1DF6, Size = 0x0CBB, IsPacked = true }, + new PackedEntry { Name = "f_chibi.sp2", Type = "image", Offset = 0x0B59AB, UnpackedSize = 0x42E, Size = 0x271, IsPacked = true }, + new PackedEntry { Name = "f_clim1.sp2", Type = "image", Offset = 0x0B5C1C, UnpackedSize = 0x66E, Size = 0x206, IsPacked = true }, + new PackedEntry { Name = "f_clim2.sp2", Type = "image", Offset = 0x0B5E22, UnpackedSize = 0x0B36, Size = 0x368, IsPacked = true }, + new PackedEntry { Name = "f_coin.sp2", Type = "image", Offset = 0x0B618A, UnpackedSize = 0x1C7, Size = 0x1CB, IsPacked = true }, + new PackedEntry { Name = "f_cura.sp2", Type = "image", Offset = 0x0B6355, UnpackedSize = 0x5D8, Size = 0x28B, IsPacked = true }, + new PackedEntry { Name = "f_door1.sp2", Type = "image", Offset = 0x0B65E0, UnpackedSize = 0x0F5, Size = 0x0F9, IsPacked = true }, + new PackedEntry { Name = "f_door10.sp2", Type = "image", Offset = 0x0B66D9, UnpackedSize = 0x95, Size = 0x99, IsPacked = true }, + new PackedEntry { Name = "f_door11.sp2", Type = "image", Offset = 0x0B6772, UnpackedSize = 0x128, Size = 0x12C, IsPacked = true }, + new PackedEntry { Name = "f_door12.sp2", Type = "image", Offset = 0x0B689E, UnpackedSize = 0x0BAE, Size = 0x157, IsPacked = true }, + new PackedEntry { Name = "f_door2.sp2", Type = "image", Offset = 0x0B69F5, UnpackedSize = 0x12B, Size = 0x12F, IsPacked = true }, + new PackedEntry { Name = "f_door3.sp2", Type = "image", Offset = 0x0B6B24, UnpackedSize = 0x146, Size = 0x14A, IsPacked = true }, + new PackedEntry { Name = "f_door4.sp2", Type = "image", Offset = 0x0B6C6E, UnpackedSize = 0x0FB, Size = 0x0FF, IsPacked = true }, + new PackedEntry { Name = "f_door5.sp2", Type = "image", Offset = 0x0B6D6D, UnpackedSize = 0x8C, Size = 0x90, IsPacked = true }, + new PackedEntry { Name = "f_door6.sp2", Type = "image", Offset = 0x0B6DFD, UnpackedSize = 0x95, Size = 0x99, IsPacked = true }, + new PackedEntry { Name = "f_door7.sp2", Type = "image", Offset = 0x0B6E96, UnpackedSize = 0x7D, Size = 0x81, IsPacked = true }, + new PackedEntry { Name = "f_door8.sp2", Type = "image", Offset = 0x0B6F17, UnpackedSize = 0x95, Size = 0x99, IsPacked = true }, + new PackedEntry { Name = "f_door9.sp2", Type = "image", Offset = 0x0B6FB0, UnpackedSize = 0x125, Size = 0x129, IsPacked = true }, + new PackedEntry { Name = "f_dummy.sp2", Type = "image", Offset = 0x0B70D9, UnpackedSize = 0x16AF, Size = 0x1153, IsPacked = true }, + new PackedEntry { Name = "f_funsui.sp2", Type = "image", Offset = 0x0B822C, UnpackedSize = 0x2D5, Size = 0x2D9, IsPacked = true }, + new PackedEntry { Name = "f_futa.sp2", Type = "image", Offset = 0x0B8505, UnpackedSize = 0x4D, Size = 0x51, IsPacked = true }, + new PackedEntry { Name = "f_gaki.sp2", Type = "image", Offset = 0x0B8556, UnpackedSize = 0x386, Size = 0x1FD, IsPacked = true }, + new PackedEntry { Name = "f_gal1.sp2", Type = "image", Offset = 0x0B8753, UnpackedSize = 0x5A2, Size = 0x3FE, IsPacked = true }, + new PackedEntry { Name = "f_gal2.sp2", Type = "image", Offset = 0x0B8B51, UnpackedSize = 0x5A2, Size = 0x407, IsPacked = true }, + new PackedEntry { Name = "f_gana.sp2", Type = "image", Offset = 0x0B8F58, UnpackedSize = 0x746, Size = 0x330, IsPacked = true }, + new PackedEntry { Name = "f_hasi.sp2", Type = "image", Offset = 0x0B9288, UnpackedSize = 0x23, Size = 0x27, IsPacked = true }, + new PackedEntry { Name = "f_hei.sp2", Type = "image", Offset = 0x0B92AF, UnpackedSize = 0x674, Size = 0x55D, IsPacked = true }, + new PackedEntry { Name = "f_icon.sp2", Type = "image", Offset = 0x0B980C, UnpackedSize = 0x503, Size = 0x459, IsPacked = true }, + new PackedEntry { Name = "f_iconb.sp2", Type = "image", Offset = 0x0B9C65, UnpackedSize = 0x3A7, Size = 0x2AE, IsPacked = true }, + new PackedEntry { Name = "f_jiji1.sp2", Type = "image", Offset = 0x0B9F13, UnpackedSize = 0x596, Size = 0x41E, IsPacked = true }, + new PackedEntry { Name = "f_jiji2.sp2", Type = "image", Offset = 0x0BA331, UnpackedSize = 0x596, Size = 0x44D, IsPacked = true }, + new PackedEntry { Name = "f_kasira.sp2", Type = "image", Offset = 0x0BA77E, UnpackedSize = 0x1202, Size = 0x367, IsPacked = true }, + new PackedEntry { Name = "f_king.sp2", Type = "image", Offset = 0x0BAAE5, UnpackedSize = 0x61A, Size = 0x37F, IsPacked = true }, + new PackedEntry { Name = "f_kuro1.sp2", Type = "image", Offset = 0x0BAE64, UnpackedSize = 0x3EC, Size = 0x2E9, IsPacked = true }, + new PackedEntry { Name = "f_kuro2.sp2", Type = "image", Offset = 0x0BB14D, UnpackedSize = 0x0A4, Size = 0x0A8, IsPacked = true }, + new PackedEntry { Name = "f_kuro3.sp2", Type = "image", Offset = 0x0BB1F5, UnpackedSize = 0x0A4, Size = 0x0A8, IsPacked = true }, + new PackedEntry { Name = "f_mado.sp2", Type = "image", Offset = 0x0BB29D, UnpackedSize = 0x644, Size = 0x457, IsPacked = true }, + new PackedEntry { Name = "f_mafin1.sp2", Type = "image", Offset = 0x0BB6F4, UnpackedSize = 0x1A6, Size = 0x8A, IsPacked = true }, + new PackedEntry { Name = "f_mafin2.sp2", Type = "image", Offset = 0x0BB77E, UnpackedSize = 0x73A, Size = 0x241, IsPacked = true }, + new PackedEntry { Name = "f_mafin3.sp2", Type = "image", Offset = 0x0BB9BF, UnpackedSize = 0x632, Size = 0x0E1, IsPacked = true }, + new PackedEntry { Name = "f_mafin4.sp2", Type = "image", Offset = 0x0BBAA0, UnpackedSize = 0x64A, Size = 0x42F, IsPacked = true }, + new PackedEntry { Name = "f_mam.sp2", Type = "image", Offset = 0x0BBECF, UnpackedSize = 0x512, Size = 0x3B0, IsPacked = true }, + new PackedEntry { Name = "f_maypl.sp2", Type = "image", Offset = 0x0BC27F, UnpackedSize = 0x842, Size = 0x168, IsPacked = true }, + new PackedEntry { Name = "f_meido.sp2", Type = "image", Offset = 0x0BC3E7, UnpackedSize = 0x5FC, Size = 0x3FE, IsPacked = true }, + new PackedEntry { Name = "f_milf1.sp2", Type = "image", Offset = 0x0BC7E5, UnpackedSize = 0x872, Size = 0x60D, IsPacked = true }, + new PackedEntry { Name = "f_milf2.sp2", Type = "image", Offset = 0x0BCDF2, UnpackedSize = 0x650, Size = 0x4C5, IsPacked = true }, + new PackedEntry { Name = "f_milf3.sp2", Type = "image", Offset = 0x0BD2B7, UnpackedSize = 0x8D2, Size = 0x0E0, IsPacked = true }, + new PackedEntry { Name = "f_mitugo.sp2", Type = "image", Offset = 0x0BD397, UnpackedSize = 0x536, Size = 0x27D, IsPacked = true }, + new PackedEntry { Name = "f_oba.sp2", Type = "image", Offset = 0x0BD614, UnpackedSize = 0x5BA, Size = 0x3EC, IsPacked = true }, + new PackedEntry { Name = "f_panna.sp2", Type = "image", Offset = 0x0BDA00, UnpackedSize = 0x93E, Size = 0x2D4, IsPacked = true }, + new PackedEntry { Name = "f_ponti.sp2", Type = "image", Offset = 0x0BDCD4, UnpackedSize = 0x78E, Size = 0x56D, IsPacked = true }, + new PackedEntry { Name = "f_queen.sp2", Type = "image", Offset = 0x0BE241, UnpackedSize = 0x902, Size = 0x2C3, IsPacked = true }, + new PackedEntry { Name = "f_riqur1.sp2", Type = "image", Offset = 0x0BE504, UnpackedSize = 0x6BC, Size = 0x4C7, IsPacked = true }, + new PackedEntry { Name = "f_riqur2.sp2", Type = "image", Offset = 0x0BE9CB, UnpackedSize = 0x572, Size = 0x0D4, IsPacked = true }, + new PackedEntry { Name = "f_russ1.sp2", Type = "image", Offset = 0x0BEA9F, UnpackedSize = 0x668, Size = 0x637, IsPacked = true }, + new PackedEntry { Name = "f_russ2.sp2", Type = "image", Offset = 0x0BF0D6, UnpackedSize = 0x6FE, Size = 0x310, IsPacked = true }, + new PackedEntry { Name = "f_sable.sp2", Type = "image", Offset = 0x0BF3E6, UnpackedSize = 0x761, Size = 0x33B, IsPacked = true }, + new PackedEntry { Name = "f_sable2.sp2", Type = "image", Offset = 0x0BF721, UnpackedSize = 0x4F7, Size = 0x4FB, IsPacked = true }, + new PackedEntry { Name = "f_selis.sp2", Type = "image", Offset = 0x0BFC1C, UnpackedSize = 0x74C, Size = 0x317, IsPacked = true }, + new PackedEntry { Name = "f_selis1.sp2", Type = "image", Offset = 0x0BFF33, UnpackedSize = 0x74C, Size = 0x2A7, IsPacked = true }, + new PackedEntry { Name = "f_selis2.sp2", Type = "image", Offset = 0x0C01DA, UnpackedSize = 0x74C, Size = 0x341, IsPacked = true }, + new PackedEntry { Name = "f_selis3.sp2", Type = "image", Offset = 0x0C051B, UnpackedSize = 0x5AB, Size = 0x1A5, IsPacked = true }, + new PackedEntry { Name = "f_shake.sp2", Type = "image", Offset = 0x0C06C0, UnpackedSize = 0x866, Size = 0x3CD, IsPacked = true }, + new PackedEntry { Name = "f_shop1.sp2", Type = "image", Offset = 0x0C0A8D, UnpackedSize = 0x620, Size = 0x460, IsPacked = true }, + new PackedEntry { Name = "f_shop3.sp2", Type = "image", Offset = 0x0C0EED, UnpackedSize = 0x620, Size = 0x460, IsPacked = true }, + new PackedEntry { Name = "f_sipul1.sp2", Type = "image", Offset = 0x0C134D, UnpackedSize = 0x3EC, Size = 0x2F0, IsPacked = true }, + new PackedEntry { Name = "f_sipul2.sp2", Type = "image", Offset = 0x0C163D, UnpackedSize = 0x6C2, Size = 0x0B5, IsPacked = true }, + new PackedEntry { Name = "f_sipul3.sp2", Type = "image", Offset = 0x0C16F2, UnpackedSize = 0x626, Size = 0x4D3, IsPacked = true }, + new PackedEntry { Name = "f_syoko.sp2", Type = "image", Offset = 0x0C1BC5, UnpackedSize = 0x5D8, Size = 0x2B8, IsPacked = true }, + new PackedEntry { Name = "f_syoko2.sp2", Type = "image", Offset = 0x0C1E7D, UnpackedSize = 0x914, Size = 0x71B, IsPacked = true }, + new PackedEntry { Name = "f_sys.sp2", Type = "image", Offset = 0x0C2598, UnpackedSize = 0x0D7, Size = 0x0DB, IsPacked = true }, + new PackedEntry { Name = "f_sys2.sp2", Type = "image", Offset = 0x0C2673, UnpackedSize = 0x0B3, Size = 0x0B7, IsPacked = true }, + new PackedEntry { Name = "f_syuku.sp2", Type = "image", Offset = 0x0C272A, UnpackedSize = 0x7B2, Size = 0x263, IsPacked = true }, + new PackedEntry { Name = "f_taka.sp2", Type = "image", Offset = 0x0C298D, UnpackedSize = 0x6B, Size = 0x6F, IsPacked = true }, + new PackedEntry { Name = "f_tira.sp2", Type = "image", Offset = 0x0C29FC, UnpackedSize = 0x79A, Size = 0x1C7, IsPacked = true }, + new PackedEntry { Name = "f_tolte.sp2", Type = "image", Offset = 0x0C2BC3, UnpackedSize = 0x710, Size = 0x4C9, IsPacked = true }, + new PackedEntry { Name = "f_tolte1.sp2", Type = "image", Offset = 0x0C308C, UnpackedSize = 0x6B, Size = 0x6F, IsPacked = true }, + new PackedEntry { Name = "f_tryu.sp2", Type = "image", Offset = 0x0C30FB, UnpackedSize = 0x716, Size = 0x338, IsPacked = true }, + new PackedEntry { Name = "f_uma.sp2", Type = "image", Offset = 0x0C3433, UnpackedSize = 0x7E2, Size = 0x670, IsPacked = true }, + new PackedEntry { Name = "f_zaha.sp2", Type = "image", Offset = 0x0C3AA3, UnpackedSize = 0x5FC, Size = 0x44A, IsPacked = true }, + new PackedEntry { Name = "g_cain.sp2", Type = "image", Offset = 0x0C3EED, UnpackedSize = 0x20AE, Size = 0x66E, IsPacked = true }, + new PackedEntry { Name = "ha.sp2", Type = "image", Offset = 0x0C455B, UnpackedSize = 0x230, Size = 0x234, IsPacked = true }, + new PackedEntry { Name = "kidan_a.sp2", Type = "image", Offset = 0x0C478F, UnpackedSize = 0x275, Size = 0x279, IsPacked = true }, + new PackedEntry { Name = "kidan_b.sp2", Type = "image", Offset = 0x0C4A08, UnpackedSize = 0x1BB, Size = 0x1BF, IsPacked = true }, + new PackedEntry { Name = "kidan_c.sp2", Type = "image", Offset = 0x0C4BC7, UnpackedSize = 0x266, Size = 0x26A, IsPacked = true }, + new PackedEntry { Name = "kin2_a.sp2", Type = "image", Offset = 0x0C4E31, UnpackedSize = 0x156B, Size = 0x1162, IsPacked = true }, + new PackedEntry { Name = "obj.sp2", Type = "image", Offset = 0x0C5F93, UnpackedSize = 0x56, Size = 0x5A, IsPacked = true }, + new PackedEntry { Name = "start.sp2", Type = "image", Offset = 0x0C5FED, UnpackedSize = 0x29C, Size = 0x2A0, IsPacked = true }, + new PackedEntry { Name = "s_cain.sp2", Type = "image", Offset = 0x0C628D, UnpackedSize = 0x33E, Size = 0x2CA, IsPacked = true }, + new PackedEntry { Name = "x_sys.sp2", Type = "image", Offset = 0x0C6557, UnpackedSize = 0x68, Size = 0x33, IsPacked = true }, + new PackedEntry { Name = "k_annin.kao", Type = "image", Offset = 0x0C658A, UnpackedSize = 0x0CC36, Size = 0x21D2, IsPacked = true }, + new PackedEntry { Name = "k_clim1.kao", Type = "image", Offset = 0x0C875C, UnpackedSize = 0x0CC36, Size = 0x1DD5, IsPacked = true }, + new PackedEntry { Name = "k_clim2.kao", Type = "image", Offset = 0x0CA531, UnpackedSize = 0x0CC36, Size = 0x16AC, IsPacked = true }, + new PackedEntry { Name = "k_gana1.kao", Type = "image", Offset = 0x0CBBDD, UnpackedSize = 0x0CC36, Size = 0x2443, IsPacked = true }, + new PackedEntry { Name = "k_gana2.kao", Type = "image", Offset = 0x0CE020, UnpackedSize = 0x0CC36, Size = 0x2573, IsPacked = true }, + new PackedEntry { Name = "k_mafi1.kao", Type = "image", Offset = 0x0D0593, UnpackedSize = 0x0CC36, Size = 0x21F9, IsPacked = true }, + new PackedEntry { Name = "k_mafi2.kao", Type = "image", Offset = 0x0D278C, UnpackedSize = 0x0CC36, Size = 0x234C, IsPacked = true }, + new PackedEntry { Name = "k_mafin1.kao", Type = "image", Offset = 0x0D4AD8, UnpackedSize = 0x0CC36, Size = 0x21F9, IsPacked = true }, + new PackedEntry { Name = "k_mafin2.kao", Type = "image", Offset = 0x0D6CD1, UnpackedSize = 0x0CC36, Size = 0x234C, IsPacked = true }, + new PackedEntry { Name = "k_milf1.kao", Type = "image", Offset = 0x0D901D, UnpackedSize = 0x0CC36, Size = 0x3349, IsPacked = true }, + new PackedEntry { Name = "k_milf2.kao", Type = "image", Offset = 0x0DC366, UnpackedSize = 0x0CC36, Size = 0x214A, IsPacked = true }, + new PackedEntry { Name = "k_panna.kao", Type = "image", Offset = 0x0DE4B0, UnpackedSize = 0x0CC36, Size = 0x2CEB, IsPacked = true }, + new PackedEntry { Name = "k_queen.kao", Type = "image", Offset = 0x0E119B, UnpackedSize = 0x0CC36, Size = 0x234A, IsPacked = true }, + new PackedEntry { Name = "k_riqu1.kao", Type = "image", Offset = 0x0E34E5, UnpackedSize = 0x0CC36, Size = 0x22ED, IsPacked = true }, + new PackedEntry { Name = "k_riqu2.kao", Type = "image", Offset = 0x0E57D2, UnpackedSize = 0x0CC36, Size = 0x1F3D, IsPacked = true }, + new PackedEntry { Name = "k_riqur1.kao", Type = "image", Offset = 0x0E770F, UnpackedSize = 0x0CC36, Size = 0x2950, IsPacked = true }, + new PackedEntry { Name = "k_riqur2.kao", Type = "image", Offset = 0x0EA05F, UnpackedSize = 0x0CC36, Size = 0x1EAF, IsPacked = true }, + new PackedEntry { Name = "k_russ1.kao", Type = "image", Offset = 0x0EBF0E, UnpackedSize = 0x0CC36, Size = 0x2420, IsPacked = true }, + new PackedEntry { Name = "k_russ2.kao", Type = "image", Offset = 0x0EE32E, UnpackedSize = 0x0CC36, Size = 0x2CE0, IsPacked = true }, + new PackedEntry { Name = "k_seli1.kao", Type = "image", Offset = 0x0F100E, UnpackedSize = 0x0CC36, Size = 0x26FD, IsPacked = true }, + new PackedEntry { Name = "k_seli2.kao", Type = "image", Offset = 0x0F370B, UnpackedSize = 0x0CC36, Size = 0x17E8, IsPacked = true }, + new PackedEntry { Name = "k_selis1.kao", Type = "image", Offset = 0x0F4EF3, UnpackedSize = 0x0CC36, Size = 0x26FD, IsPacked = true }, + new PackedEntry { Name = "k_selis2.kao", Type = "image", Offset = 0x0F75F0, UnpackedSize = 0x0CC36, Size = 0x17E8, IsPacked = true }, + new PackedEntry { Name = "k_shake.kao", Type = "image", Offset = 0x0F8DD8, UnpackedSize = 0x0CC36, Size = 0x1755, IsPacked = true }, + new PackedEntry { Name = "k_syoko.kao", Type = "image", Offset = 0x0FA52D, UnpackedSize = 0x0CC36, Size = 0x1FF6, IsPacked = true }, + new PackedEntry { Name = "k_syuku.kao", Type = "image", Offset = 0x0FC523, UnpackedSize = 0x0CC36, Size = 0x2881, IsPacked = true }, + new PackedEntry { Name = "k_tira.kao", Type = "image", Offset = 0x0FEDA4, UnpackedSize = 0x0CC36, Size = 0x1BF2, IsPacked = true }, + new PackedEntry { Name = "k_tolte.kao", Type = "image", Offset = 0x100996, UnpackedSize = 0x0CC36, Size = 0x329B, IsPacked = true }, + } + }, + { + "ALLMAP.273", new List() { + new PackedEntry { Name = "allmap.ma2", Offset = 0x0, UnpackedSize = 0x5DE0, Size = 0x1E4D, IsPacked = true }, + new PackedEntry { Name = "bukiya.ma2", Offset = 0x1E4D, UnpackedSize = 0x0DCC, Size = 0x3B8, IsPacked = true }, + new PackedEntry { Name = "cron00.ma2", Offset = 0x2205, UnpackedSize = 0x1240, Size = 0x2F5, IsPacked = true }, + new PackedEntry { Name = "cudu00.ma2", Offset = 0x24FA, UnpackedSize = 0x6998, Size = 0x96F, IsPacked = true }, + new PackedEntry { Name = "cudu01.ma2", Offset = 0x2E69, UnpackedSize = 0x4670, Size = 0x706, IsPacked = true }, + new PackedEntry { Name = "cudu02.ma2", Offset = 0x356F, UnpackedSize = 0x4670, Size = 0x78F, IsPacked = true }, + new PackedEntry { Name = "cudu03.ma2", Offset = 0x3CFE, UnpackedSize = 0x3AB8, Size = 0x392, IsPacked = true }, + new PackedEntry { Name = "cudu04.ma2", Offset = 0x4090, UnpackedSize = 0x3AB8, Size = 0x2B2, IsPacked = true }, + new PackedEntry { Name = "cudu05.ma2", Offset = 0x4342, UnpackedSize = 0x41C0, Size = 0x674, IsPacked = true }, + new PackedEntry { Name = "cudu06.ma2", Offset = 0x49B6, UnpackedSize = 0x3AB8, Size = 0x58E, IsPacked = true }, + new PackedEntry { Name = "cudu07.ma2", Offset = 0x4F44, UnpackedSize = 0x0FC0, Size = 0x3C4, IsPacked = true }, + new PackedEntry { Name = "cudu08.ma2", Offset = 0x5308, UnpackedSize = 0x3AB8, Size = 0x51F, IsPacked = true }, + new PackedEntry { Name = "cudu09.ma2", Offset = 0x5827, UnpackedSize = 0x11B4, Size = 0x27D, IsPacked = true }, + new PackedEntry { Name = "cudu10.ma2", Offset = 0x5AA4, UnpackedSize = 0x0FC0, Size = 0x210, IsPacked = true }, + new PackedEntry { Name = "doguya.ma2", Offset = 0x5CB4, UnpackedSize = 0x0DCC, Size = 0x393, IsPacked = true }, + new PackedEntry { Name = "dokutu01.ma2", Offset = 0x6047, UnpackedSize = 0x1790, Size = 0x598, IsPacked = true }, + new PackedEntry { Name = "dokutu02.ma2", Offset = 0x65DF, UnpackedSize = 0x1790, Size = 0x56A, IsPacked = true }, + new PackedEntry { Name = "dokutu03.ma2", Offset = 0x6B49, UnpackedSize = 0x65B0, Size = 0x0B89, IsPacked = true }, + new PackedEntry { Name = "dokutu04.ma2", Offset = 0x76D2, UnpackedSize = 0x44E0, Size = 0x0CD0, IsPacked = true }, + new PackedEntry { Name = "dokutu05.ma2", Offset = 0x83A2, UnpackedSize = 0x5DE0, Size = 0x0C06, IsPacked = true }, + new PackedEntry { Name = "dokutu06.ma2", Offset = 0x8FA8, UnpackedSize = 0x5DE0, Size = 0x0BD9, IsPacked = true }, + new PackedEntry { Name = "dokutu07.ma2", Offset = 0x9B81, UnpackedSize = 0x6BF0, Size = 0x0FA2, IsPacked = true }, + new PackedEntry { Name = "dokutu08.ma2", Offset = 0x0AB23, UnpackedSize = 0x1C40, Size = 0x5D9, IsPacked = true }, + new PackedEntry { Name = "dokutu09.ma2", Offset = 0x0B0FC, UnpackedSize = 0x2668, Size = 0x73C, IsPacked = true }, + new PackedEntry { Name = "flap00.ma2", Offset = 0x0B838, UnpackedSize = 0x2BE0, Size = 0x1134, IsPacked = true }, + new PackedEntry { Name = "flap01.ma2", Offset = 0x0C96C, UnpackedSize = 0x82B4, Size = 0x1293, IsPacked = true }, + new PackedEntry { Name = "flap02.ma2", Offset = 0x0DBFF, UnpackedSize = 0x75F0, Size = 0x0A08, IsPacked = true }, + new PackedEntry { Name = "flap03.ma2", Offset = 0x0E607, UnpackedSize = 0x5DE0, Size = 0x836, IsPacked = true }, + new PackedEntry { Name = "flap04.ma2", Offset = 0x0EE3D, UnpackedSize = 0x2668, Size = 0x66F, IsPacked = true }, + new PackedEntry { Name = "flap05.ma2", Offset = 0x0F4AC, UnpackedSize = 0x6A60, Size = 0x20E0, IsPacked = true }, + new PackedEntry { Name = "flap06.ma2", Offset = 0x1158C, UnpackedSize = 0x30F4, Size = 0x922, IsPacked = true }, + new PackedEntry { Name = "flap07.ma2", Offset = 0x11EAE, UnpackedSize = 0x7EB0, Size = 0x0DC7, IsPacked = true }, + new PackedEntry { Name = "flap08.ma2", Offset = 0x12C75, UnpackedSize = 0x36D0, Size = 0x0DE9, IsPacked = true }, + new PackedEntry { Name = "flap09.ma2", Offset = 0x13A5E, UnpackedSize = 0x4670, Size = 0x16D7, IsPacked = true }, + new PackedEntry { Name = "flap10.ma2", Offset = 0x15135, UnpackedSize = 0x2348, Size = 0x5AA, IsPacked = true }, + new PackedEntry { Name = "flap11.ma2", Offset = 0x156DF, UnpackedSize = 0x1D6C, Size = 0x49F, IsPacked = true }, + new PackedEntry { Name = "flap12.ma2", Offset = 0x15B7E, UnpackedSize = 0x1B78, Size = 0x638, IsPacked = true }, + new PackedEntry { Name = "flap13.ma2", Offset = 0x161B6, UnpackedSize = 0x0FC0, Size = 0x444, IsPacked = true }, + new PackedEntry { Name = "flap14.ma2", Offset = 0x165FA, UnpackedSize = 0x0FC0, Size = 0x353, IsPacked = true }, + new PackedEntry { Name = "flap15.ma2", Offset = 0x1694D, UnpackedSize = 0x0FC0, Size = 0x34F, IsPacked = true }, + new PackedEntry { Name = "flap16.ma2", Offset = 0x16C9C, UnpackedSize = 0x0FC0, Size = 0x36E, IsPacked = true }, + new PackedEntry { Name = "flap17.ma2", Offset = 0x1700A, UnpackedSize = 0x0FC0, Size = 0x3C0, IsPacked = true }, + new PackedEntry { Name = "flap18.ma2", Offset = 0x173CA, UnpackedSize = 0x1344, Size = 0x597, IsPacked = true }, + new PackedEntry { Name = "fond00.ma2", Offset = 0x17961, UnpackedSize = 0x1F60, Size = 0x822, IsPacked = true }, + new PackedEntry { Name = "fond01.ma2", Offset = 0x18183, UnpackedSize = 0x2730, Size = 0x93E, IsPacked = true }, + new PackedEntry { Name = "fond02.ma2", Offset = 0x18AC1, UnpackedSize = 0x2F00, Size = 0x0B19, IsPacked = true }, + new PackedEntry { Name = "fond03.ma2", Offset = 0x195DA, UnpackedSize = 0x1B78, Size = 0x79B, IsPacked = true }, + new PackedEntry { Name = "fond04.ma2", Offset = 0x19D75, UnpackedSize = 0x0EF8, Size = 0x528, IsPacked = true }, + new PackedEntry { Name = "fond05.ma2", Offset = 0x1A29D, UnpackedSize = 0x29BA, Size = 0x929, IsPacked = true }, + new PackedEntry { Name = "fond06.ma2", Offset = 0x1ABC6, UnpackedSize = 0x2F00, Size = 0x0B76, IsPacked = true }, + new PackedEntry { Name = "fond07.ma2", Offset = 0x1B73C, UnpackedSize = 0x1AD8, Size = 0x6E4, IsPacked = true }, + new PackedEntry { Name = "fond08.ma2", Offset = 0x1BE20, UnpackedSize = 0x1984, Size = 0x8AF, IsPacked = true }, + new PackedEntry { Name = "fond09.ma2", Offset = 0x1C6CF, UnpackedSize = 0x0B10, Size = 0x325, IsPacked = true }, + new PackedEntry { Name = "garu01.ma2", Offset = 0x1C9F4, UnpackedSize = 0x0FC0, Size = 0x2E8, IsPacked = true }, + new PackedEntry { Name = "garu02.ma2", Offset = 0x1CCDC, UnpackedSize = 0x2F00, Size = 0x7CF, IsPacked = true }, + new PackedEntry { Name = "garu03.ma2", Offset = 0x1D4AB, UnpackedSize = 0x1F60, Size = 0x405, IsPacked = true }, + new PackedEntry { Name = "garu04.ma2", Offset = 0x1D8B0, UnpackedSize = 0x2620, Size = 0x520, IsPacked = true }, + new PackedEntry { Name = "garu05.ma2", Offset = 0x1DDD0, UnpackedSize = 0x30E0, Size = 0x70A, IsPacked = true }, + new PackedEntry { Name = "garu06.ma2", Offset = 0x1E4DA, UnpackedSize = 0x3EA0, Size = 0x0A74, IsPacked = true }, + new PackedEntry { Name = "garu07.ma2", Offset = 0x1EF4E, UnpackedSize = 0x4F20, Size = 0x0AD7, IsPacked = true }, + new PackedEntry { Name = "garu08.ma2", Offset = 0x1FA25, UnpackedSize = 0x1600, Size = 0x392, IsPacked = true }, + new PackedEntry { Name = "garu09.ma2", Offset = 0x1FDB7, UnpackedSize = 0x2620, Size = 0x5D9, IsPacked = true }, + new PackedEntry { Name = "garu10.ma2", Offset = 0x20390, UnpackedSize = 0x2620, Size = 0x663, IsPacked = true }, + new PackedEntry { Name = "hbmura01.ma2", Offset = 0x209F3, UnpackedSize = 0x5FD4, Size = 0x1F88, IsPacked = true }, + new PackedEntry { Name = "isek00.ma2", Offset = 0x2297B, UnpackedSize = 0x3C20, Size = 0x0D05, IsPacked = true }, + new PackedEntry { Name = "isek01.ma2", Offset = 0x23680, UnpackedSize = 0x500C, Size = 0x8AD, IsPacked = true }, + new PackedEntry { Name = "isek02.ma2", Offset = 0x23F2D, UnpackedSize = 0x8130, Size = 0x0D57, IsPacked = true }, + new PackedEntry { Name = "isek03.ma2", Offset = 0x24C84, UnpackedSize = 0x3470, Size = 0x697, IsPacked = true }, + new PackedEntry { Name = "isek04.ma2", Offset = 0x2531B, UnpackedSize = 0x7870, Size = 0x0B6F, IsPacked = true }, + new PackedEntry { Name = "isek05.ma2", Offset = 0x25E8A, UnpackedSize = 0x99E0, Size = 0x0D69, IsPacked = true }, + new PackedEntry { Name = "isek06.ma2", Offset = 0x26BF3, UnpackedSize = 0x5E58, Size = 0x8E9, IsPacked = true }, + new PackedEntry { Name = "jobin.ma2", Offset = 0x274DC, UnpackedSize = 0x1470, Size = 0x3A1, IsPacked = true }, + new PackedEntry { Name = "jobuki.ma2", Offset = 0x2787D, UnpackedSize = 0x1E34, Size = 0x3E9, IsPacked = true }, + new PackedEntry { Name = "jodog.ma2", Offset = 0x27C66, UnpackedSize = 0x159C, Size = 0x2E9, IsPacked = true }, + new PackedEntry { Name = "jofuka1.ma2", Offset = 0x27F4F, UnpackedSize = 0x0CA0, Size = 0x320, IsPacked = true }, + new PackedEntry { Name = "jofuka2.ma2", Offset = 0x2826F, UnpackedSize = 0x0CA0, Size = 0x2E8, IsPacked = true }, + new PackedEntry { Name = "jofuka3.ma2", Offset = 0x28557, UnpackedSize = 0x1920, Size = 0x270, IsPacked = true }, + new PackedEntry { Name = "joido.ma2", Offset = 0x287C7, UnpackedSize = 0x0FC0, Size = 0x1CC, IsPacked = true }, + new PackedEntry { Name = "joisya.ma2", Offset = 0x28993, UnpackedSize = 0x2460, Size = 0x6AF, IsPacked = true }, + new PackedEntry { Name = "jomin1.ma2", Offset = 0x29042, UnpackedSize = 0x159C, Size = 0x41E, IsPacked = true }, + new PackedEntry { Name = "jomin2.ma2", Offset = 0x29460, UnpackedSize = 0x159C, Size = 0x3D3, IsPacked = true }, + new PackedEntry { Name = "jouka.ma2", Offset = 0x29833, UnpackedSize = 0x99E0, Size = 0x1C02, IsPacked = true }, + new PackedEntry { Name = "jouma.ma2", Offset = 0x2B435, UnpackedSize = 0x1880, Size = 0x4B3, IsPacked = true }, + new PackedEntry { Name = "joyado1.ma2", Offset = 0x2B8E8, UnpackedSize = 0x25A0, Size = 0x5E4, IsPacked = true }, + new PackedEntry { Name = "joyado2.ma2", Offset = 0x2BECC, UnpackedSize = 0x25A0, Size = 0x4CA, IsPacked = true }, + new PackedEntry { Name = "kain1.ma2", Offset = 0x2C396, UnpackedSize = 0x1FC4, Size = 0x7E1, IsPacked = true }, + new PackedEntry { Name = "kain2.ma2", Offset = 0x2CB77, UnpackedSize = 0x1FC4, Size = 0x676, IsPacked = true }, + new PackedEntry { Name = "kaiz00.ma2", Offset = 0x2D1ED, UnpackedSize = 0x88D8, Size = 0x7EE, IsPacked = true }, + new PackedEntry { Name = "kaiz01.ma2", Offset = 0x2D9DB, UnpackedSize = 0x1D6C, Size = 0x261, IsPacked = true }, + new PackedEntry { Name = "kaiz02.ma2", Offset = 0x2DC3C, UnpackedSize = 0x1D6C, Size = 0x23C, IsPacked = true }, + new PackedEntry { Name = "kaiz03.ma2", Offset = 0x2DE78, UnpackedSize = 0x893C, Size = 0x922, IsPacked = true }, + new PackedEntry { Name = "kaiz04.ma2", Offset = 0x2E79A, UnpackedSize = 0x9EB8, Size = 0x0CCC, IsPacked = true }, + new PackedEntry { Name = "kaiz05.ma2", Offset = 0x2F466, UnpackedSize = 0x6D80, Size = 0x9F6, IsPacked = true }, + new PackedEntry { Name = "kaiz06.ma2", Offset = 0x2FE5C, UnpackedSize = 0x6D80, Size = 0x9F2, IsPacked = true }, + new PackedEntry { Name = "kaiz07.ma2", Offset = 0x3084E, UnpackedSize = 0x2348, Size = 0x905, IsPacked = true }, + new PackedEntry { Name = "katabuki.ma2", Offset = 0x31153, UnpackedSize = 0x1088, Size = 0x3DD, IsPacked = true }, + new PackedEntry { Name = "katadogu.ma2", Offset = 0x31530, UnpackedSize = 0x0DCC, Size = 0x33F, IsPacked = true }, + new PackedEntry { Name = "katamin1.ma2", Offset = 0x3186F, UnpackedSize = 0x1600, Size = 0x4BB, IsPacked = true }, + new PackedEntry { Name = "katamin2.ma2", Offset = 0x31D2A, UnpackedSize = 0x1678, Size = 0x555, IsPacked = true }, + new PackedEntry { Name = "katamina.ma2", Offset = 0x3227F, UnpackedSize = 0x1560, Size = 0x71C, IsPacked = true }, + new PackedEntry { Name = "katania.ma2", Offset = 0x3299B, UnpackedSize = 0x7DE8, Size = 0x219D, IsPacked = true }, + new PackedEntry { Name = "kataryo1.ma2", Offset = 0x34B38, UnpackedSize = 0x1678, Size = 0x56D, IsPacked = true }, + new PackedEntry { Name = "kataryo2.ma2", Offset = 0x350A5, UnpackedSize = 0x1470, Size = 0x5EF, IsPacked = true }, + new PackedEntry { Name = "katasou1.ma2", Offset = 0x35694, UnpackedSize = 0x0FC0, Size = 0x2EA, IsPacked = true }, + new PackedEntry { Name = "katasou2.ma2", Offset = 0x3597E, UnpackedSize = 0x0FC0, Size = 0x31B, IsPacked = true }, + new PackedEntry { Name = "katasyo.ma2", Offset = 0x35C99, UnpackedSize = 0x0E30, Size = 0x435, IsPacked = true }, + new PackedEntry { Name = "katayad1.ma2", Offset = 0x360CE, UnpackedSize = 0x0DCC, Size = 0x3A9, IsPacked = true }, + new PackedEntry { Name = "katayad2.ma2", Offset = 0x36477, UnpackedSize = 0x15A8, Size = 0x477, IsPacked = true }, + new PackedEntry { Name = "koro00.ma2", Offset = 0x368EE, UnpackedSize = 0x14A0, Size = 0x51F, IsPacked = true }, + new PackedEntry { Name = "koro01.ma2", Offset = 0x36E0D, UnpackedSize = 0x13A8, Size = 0x3FC, IsPacked = true }, + new PackedEntry { Name = "koro02.ma2", Offset = 0x37209, UnpackedSize = 0x1920, Size = 0x2B7, IsPacked = true }, + new PackedEntry { Name = "koro03.ma2", Offset = 0x374C0, UnpackedSize = 0x36D0, Size = 0x840, IsPacked = true }, + new PackedEntry { Name = "kuro00.ma2", Offset = 0x37D00, UnpackedSize = 0x0FC0, Size = 0x548, IsPacked = true }, + new PackedEntry { Name = "kuro01.ma2", Offset = 0x38248, UnpackedSize = 0x3C48, Size = 0x813, IsPacked = true }, + new PackedEntry { Name = "kuro02.ma2", Offset = 0x38A5B, UnpackedSize = 0x3C48, Size = 0x8F2, IsPacked = true }, + new PackedEntry { Name = "kuro03.ma2", Offset = 0x3934D, UnpackedSize = 0x5DE0, Size = 0x0E6E, IsPacked = true }, + new PackedEntry { Name = "last00.ma2", Offset = 0x3A1BB, UnpackedSize = 0x0FC0, Size = 0x609, IsPacked = true }, + new PackedEntry { Name = "last01.ma2", Offset = 0x3A7C4, UnpackedSize = 0x12E0, Size = 0x223, IsPacked = true }, + new PackedEntry { Name = "last02.ma2", Offset = 0x3A9E7, UnpackedSize = 0x2348, Size = 0x2EC, IsPacked = true }, + new PackedEntry { Name = "last03.ma2", Offset = 0x3ACD3, UnpackedSize = 0x19E8, Size = 0x203, IsPacked = true }, + new PackedEntry { Name = "last04.ma2", Offset = 0x3AED6, UnpackedSize = 0x2348, Size = 0x2D0, IsPacked = true }, + new PackedEntry { Name = "last05.ma2", Offset = 0x3B1A6, UnpackedSize = 0x32C0, Size = 0x341, IsPacked = true }, + new PackedEntry { Name = "last06.ma2", Offset = 0x3B4E7, UnpackedSize = 0x52F0, Size = 0x384, IsPacked = true }, + new PackedEntry { Name = "last07.ma2", Offset = 0x3B86B, UnpackedSize = 0x1BA0, Size = 0x226, IsPacked = true }, + new PackedEntry { Name = "last08.ma2", Offset = 0x3BA91, UnpackedSize = 0x19E8, Size = 0x216, IsPacked = true }, + new PackedEntry { Name = "last09.ma2", Offset = 0x3BCA7, UnpackedSize = 0x19E8, Size = 0x216, IsPacked = true }, + new PackedEntry { Name = "last10.ma2", Offset = 0x3BEBD, UnpackedSize = 0x19E8, Size = 0x1FD, IsPacked = true }, + new PackedEntry { Name = "last11.ma2", Offset = 0x3C0BA, UnpackedSize = 0x2B18, Size = 0x898, IsPacked = true }, + new PackedEntry { Name = "last12.ma2", Offset = 0x3C952, UnpackedSize = 0x13A8, Size = 0x444, IsPacked = true }, + new PackedEntry { Name = "last13.ma2", Offset = 0x3CD96, UnpackedSize = 0x4E40, Size = 0x691, IsPacked = true }, + new PackedEntry { Name = "last14.ma2", Offset = 0x3D427, UnpackedSize = 0x15EC, Size = 0x556, IsPacked = true }, + new PackedEntry { Name = "last15.ma2", Offset = 0x3D97D, UnpackedSize = 0x5DE0, Size = 0x922, IsPacked = true }, + new PackedEntry { Name = "last16.ma2", Offset = 0x3E29F, UnpackedSize = 0x1FC4, Size = 0x65E, IsPacked = true }, + new PackedEntry { Name = "last17.ma2", Offset = 0x3E8FD, UnpackedSize = 0x13A8, Size = 0x3F8, IsPacked = true }, + new PackedEntry { Name = "last18.ma2", Offset = 0x3ECF5, UnpackedSize = 0x1FC4, Size = 0x62D, IsPacked = true }, + new PackedEntry { Name = "last19.ma2", Offset = 0x3F322, UnpackedSize = 0x2730, Size = 0x6C8, IsPacked = true }, + new PackedEntry { Name = "last20.ma2", Offset = 0x3F9EA, UnpackedSize = 0x2BE0, Size = 0x50C, IsPacked = true }, + new PackedEntry { Name = "last21.ma2", Offset = 0x3FEF6, UnpackedSize = 0x0FC0, Size = 0x554, IsPacked = true }, + new PackedEntry { Name = "last22.ma2", Offset = 0x4044A, UnpackedSize = 0x0FC0, Size = 0x562, IsPacked = true }, + new PackedEntry { Name = "last23.ma2", Offset = 0x409AC, UnpackedSize = 0x0FC0, Size = 0x26A, IsPacked = true }, + new PackedEntry { Name = "last24.ma2", Offset = 0x40C16, UnpackedSize = 0x0FC0, Size = 0x468, IsPacked = true }, + new PackedEntry { Name = "matu00.ma2", Offset = 0x4107E, UnpackedSize = 0x99E0, Size = 0x1BE6, IsPacked = true }, + new PackedEntry { Name = "ojou01.ma2", Offset = 0x42C64, UnpackedSize = 0x63A8, Size = 0x1146, IsPacked = true }, + new PackedEntry { Name = "ojou02.ma2", Offset = 0x43DAA, UnpackedSize = 0x4A80, Size = 0x6F0, IsPacked = true }, + new PackedEntry { Name = "ojou03.ma2", Offset = 0x4449A, UnpackedSize = 0x3F04, Size = 0x0AE9, IsPacked = true }, + new PackedEntry { Name = "ojou04.ma2", Offset = 0x44F83, UnpackedSize = 0x3C20, Size = 0x0C20, IsPacked = true }, + new PackedEntry { Name = "ojou05.ma2", Offset = 0x45BA3, UnpackedSize = 0x1F60, Size = 0x5B2, IsPacked = true }, + new PackedEntry { Name = "ojou06.ma2", Offset = 0x46155, UnpackedSize = 0x2D20, Size = 0x471, IsPacked = true }, + new PackedEntry { Name = "ojou07.ma2", Offset = 0x465C6, UnpackedSize = 0x5610, Size = 0x74A, IsPacked = true }, + new PackedEntry { Name = "ojou08.ma2", Offset = 0x46D10, UnpackedSize = 0x5610, Size = 0x810, IsPacked = true }, + new PackedEntry { Name = "ojou09.ma2", Offset = 0x47520, UnpackedSize = 0x5610, Size = 0x99E, IsPacked = true }, + new PackedEntry { Name = "ojou10.ma2", Offset = 0x47EBE, UnpackedSize = 0x5610, Size = 0x9A0, IsPacked = true }, + new PackedEntry { Name = "ojou11.ma2", Offset = 0x4885E, UnpackedSize = 0x5610, Size = 0x859, IsPacked = true }, + new PackedEntry { Name = "ojou12.ma2", Offset = 0x490B7, UnpackedSize = 0x5610, Size = 0x8B3, IsPacked = true }, + new PackedEntry { Name = "ojou13.ma2", Offset = 0x4996A, UnpackedSize = 0x5610, Size = 0x941, IsPacked = true }, + new PackedEntry { Name = "ojou14.ma2", Offset = 0x4A2AB, UnpackedSize = 0x1920, Size = 0x229, IsPacked = true }, + new PackedEntry { Name = "ojou15.ma2", Offset = 0x4A4D4, UnpackedSize = 0x5610, Size = 0x722, IsPacked = true }, + new PackedEntry { Name = "ojou16.ma2", Offset = 0x4ABF6, UnpackedSize = 0x5610, Size = 0x7D7, IsPacked = true }, + new PackedEntry { Name = "ojou17.ma2", Offset = 0x4B3CD, UnpackedSize = 0x5610, Size = 0x7CF, IsPacked = true }, + new PackedEntry { Name = "ojou18.ma2", Offset = 0x4BB9C, UnpackedSize = 0x5610, Size = 0x73A, IsPacked = true }, + new PackedEntry { Name = "ojou19.ma2", Offset = 0x4C2D6, UnpackedSize = 0x5610, Size = 0x707, IsPacked = true }, + new PackedEntry { Name = "ojou20.ma2", Offset = 0x4C9DD, UnpackedSize = 0x5610, Size = 0x5F8, IsPacked = true }, + new PackedEntry { Name = "ojou21.ma2", Offset = 0x4CFD5, UnpackedSize = 0x2E9C, Size = 0x34C, IsPacked = true }, + new PackedEntry { Name = "ojou22.ma2", Offset = 0x4D321, UnpackedSize = 0x5610, Size = 0x869, IsPacked = true }, + new PackedEntry { Name = "oldw00.ma2", Offset = 0x4DB8A, UnpackedSize = 0x0B10, Size = 0x25D, IsPacked = true }, + new PackedEntry { Name = "oldw01.ma2", Offset = 0x4DDE7, UnpackedSize = 0x4670, Size = 0x122D, IsPacked = true }, + new PackedEntry { Name = "oldw02.ma2", Offset = 0x4F014, UnpackedSize = 0x12E0, Size = 0x347, IsPacked = true }, + new PackedEntry { Name = "oldw03.ma2", Offset = 0x4F35B, UnpackedSize = 0x0A70, Size = 0x25C, IsPacked = true }, + new PackedEntry { Name = "oldw04.ma2", Offset = 0x4F5B7, UnpackedSize = 0x0A70, Size = 0x269, IsPacked = true }, + new PackedEntry { Name = "oldw05.ma2", Offset = 0x4F820, UnpackedSize = 0x1088, Size = 0x27C, IsPacked = true }, + new PackedEntry { Name = "oldw06.ma2", Offset = 0x4FA9C, UnpackedSize = 0x48A0, Size = 0x0E99, IsPacked = true }, + new PackedEntry { Name = "oldw07.ma2", Offset = 0x50935, UnpackedSize = 0x0AC0, Size = 0x275, IsPacked = true }, + new PackedEntry { Name = "oldw08.ma2", Offset = 0x50BAA, UnpackedSize = 0x0AC0, Size = 0x2CF, IsPacked = true }, + new PackedEntry { Name = "oldw09.ma2", Offset = 0x50E79, UnpackedSize = 0x0AC0, Size = 0x286, IsPacked = true }, + new PackedEntry { Name = "oldw10.ma2", Offset = 0x510FF, UnpackedSize = 0x19E8, Size = 0x41A, IsPacked = true }, + new PackedEntry { Name = "oldw11.ma2", Offset = 0x51519, UnpackedSize = 0x2348, Size = 0x4B9, IsPacked = true }, + new PackedEntry { Name = "oldw12.ma2", Offset = 0x519D2, UnpackedSize = 0x7F0, Size = 0x4DF, IsPacked = true }, + new PackedEntry { Name = "omake.ma2", Offset = 0x51EB1, UnpackedSize = 0x7F0, Size = 0x2C6, IsPacked = true }, + new PackedEntry { Name = "omake2.ma2", Offset = 0x52177, UnpackedSize = 0x7F0, Size = 0x2B9, IsPacked = true }, + new PackedEntry { Name = "paremina.ma2", Offset = 0x52430, UnpackedSize = 0x1F60, Size = 0x7D1, IsPacked = true }, + new PackedEntry { Name = "parerumo.ma2", Offset = 0x52C01, UnpackedSize = 0x8DBA, Size = 0x20B6, IsPacked = true }, + new PackedEntry { Name = "pargil.ma2", Offset = 0x54CB7, UnpackedSize = 0x2280, Size = 0x3F6, IsPacked = true }, + new PackedEntry { Name = "parsaka.ma2", Offset = 0x550AD, UnpackedSize = 0x2280, Size = 0x40C, IsPacked = true }, + new PackedEntry { Name = "paruma.ma2", Offset = 0x554B9, UnpackedSize = 0x1880, Size = 0x4B3, IsPacked = true }, + new PackedEntry { Name = "paryad1.ma2", Offset = 0x5596C, UnpackedSize = 0x1B32, Size = 0x552, IsPacked = true }, + new PackedEntry { Name = "paryad2.ma2", Offset = 0x55EBE, UnpackedSize = 0x1B32, Size = 0x3F9, IsPacked = true }, + new PackedEntry { Name = "saba00.ma2", Offset = 0x562B7, UnpackedSize = 0x3AB8, Size = 0x826, IsPacked = true }, + new PackedEntry { Name = "saba01.ma2", Offset = 0x56ADD, UnpackedSize = 0x2348, Size = 0x53D, IsPacked = true }, + new PackedEntry { Name = "saba02.ma2", Offset = 0x5701A, UnpackedSize = 0x4670, Size = 0x7AD, IsPacked = true }, + new PackedEntry { Name = "saba03.ma2", Offset = 0x577C7, UnpackedSize = 0x3EA0, Size = 0x5A1, IsPacked = true }, + new PackedEntry { Name = "saba04.ma2", Offset = 0x57D68, UnpackedSize = 0x1C40, Size = 0x4B8, IsPacked = true }, + new PackedEntry { Name = "sakaba.ma2", Offset = 0x58220, UnpackedSize = 0x0B60, Size = 0x42B, IsPacked = true }, + new PackedEntry { Name = "sepu00.ma2", Offset = 0x5864B, UnpackedSize = 0x4F3A, Size = 0x1378, IsPacked = true }, + new PackedEntry { Name = "sepu01.ma2", Offset = 0x599C3, UnpackedSize = 0x980, Size = 0x252, IsPacked = true }, + new PackedEntry { Name = "sepu02.ma2", Offset = 0x59C15, UnpackedSize = 0x8E0, Size = 0x24D, IsPacked = true }, + new PackedEntry { Name = "sepu03.ma2", Offset = 0x59E62, UnpackedSize = 0x980, Size = 0x26E, IsPacked = true }, + new PackedEntry { Name = "sepu04.ma2", Offset = 0x5A0D0, UnpackedSize = 0x980, Size = 0x234, IsPacked = true }, + new PackedEntry { Name = "sepu05.ma2", Offset = 0x5A304, UnpackedSize = 0x1AB0, Size = 0x4A5, IsPacked = true }, + new PackedEntry { Name = "sepu06.ma2", Offset = 0x5A7A9, UnpackedSize = 0x16A0, Size = 0x3AF, IsPacked = true }, + new PackedEntry { Name = "sepu07.ma2", Offset = 0x5AB58, UnpackedSize = 0x6290, Size = 0x718, IsPacked = true }, + new PackedEntry { Name = "sepu08.ma2", Offset = 0x5B270, UnpackedSize = 0x3200, Size = 0x3C5, IsPacked = true }, + new PackedEntry { Name = "sepu09.ma2", Offset = 0x5B635, UnpackedSize = 0x25A0, Size = 0x443, IsPacked = true }, + new PackedEntry { Name = "sepu10.ma2", Offset = 0x5BA78, UnpackedSize = 0x5740, Size = 0x674, IsPacked = true }, + new PackedEntry { Name = "sepu11.ma2", Offset = 0x5C0EC, UnpackedSize = 0x3B80, Size = 0x457, IsPacked = true }, + new PackedEntry { Name = "sepu12.ma2", Offset = 0x5C543, UnpackedSize = 0x32C0, Size = 0x5CF, IsPacked = true }, + new PackedEntry { Name = "sepu13.ma2", Offset = 0x5CB12, UnpackedSize = 0x3AB8, Size = 0x387, IsPacked = true }, + new PackedEntry { Name = "sepu14.ma2", Offset = 0x5CE99, UnpackedSize = 0x2BE0, Size = 0x69E, IsPacked = true }, + new PackedEntry { Name = "sima00.ma2", Offset = 0x5D537, UnpackedSize = 0x0FC0, Size = 0x548, IsPacked = true }, + new PackedEntry { Name = "sima01.ma2", Offset = 0x5DA7F, UnpackedSize = 0x5DE0, Size = 0x77A, IsPacked = true }, + new PackedEntry { Name = "sima02.ma2", Offset = 0x5E1F9, UnpackedSize = 0x4E40, Size = 0x70F, IsPacked = true }, + new PackedEntry { Name = "sima03.ma2", Offset = 0x5E908, UnpackedSize = 0x4E40, Size = 0x634, IsPacked = true }, + new PackedEntry { Name = "sima04.ma2", Offset = 0x5EF3C, UnpackedSize = 0x5DE0, Size = 0x7E5, IsPacked = true }, + new PackedEntry { Name = "sima05.ma2", Offset = 0x5F721, UnpackedSize = 0x5DE0, Size = 0x86D, IsPacked = true }, + new PackedEntry { Name = "sima06.ma2", Offset = 0x5FF8E, UnpackedSize = 0x1F60, Size = 0x486, IsPacked = true }, + new PackedEntry { Name = "sima07.ma2", Offset = 0x60414, UnpackedSize = 0x0CA0, Size = 0x1DD, IsPacked = true }, + new PackedEntry { Name = "sougen.ma2", Offset = 0x605F1, UnpackedSize = 0x0FC0, Size = 0x604, IsPacked = true }, + new PackedEntry { Name = "syoko01.ma2", Offset = 0x60BF5, UnpackedSize = 0x3DA6, Size = 0x0B2E, IsPacked = true }, + new PackedEntry { Name = "syoko02.ma2", Offset = 0x61723, UnpackedSize = 0x1CD6, Size = 0x7F8, IsPacked = true }, + new PackedEntry { Name = "syud00.ma2", Offset = 0x61F1B, UnpackedSize = 0x0B60, Size = 0x4F1, IsPacked = true }, + new PackedEntry { Name = "syud01.ma2", Offset = 0x6240C, UnpackedSize = 0x5480, Size = 0x0E12, IsPacked = true }, + new PackedEntry { Name = "tidu00.ma2", Offset = 0x6321E, UnpackedSize = 0x5FD4, Size = 0x103A, IsPacked = true }, + new PackedEntry { Name = "tidu01.ma2", Offset = 0x64258, UnpackedSize = 0x8B30, Size = 0x0BB0, IsPacked = true }, + new PackedEntry { Name = "tidu02.ma2", Offset = 0x64E08, UnpackedSize = 0x8298, Size = 0x1008, IsPacked = true }, + new PackedEntry { Name = "tidu03.ma2", Offset = 0x65E10, UnpackedSize = 0x70A0, Size = 0x0B70, IsPacked = true }, + new PackedEntry { Name = "tidu04.ma2", Offset = 0x66980, UnpackedSize = 0x89A0, Size = 0x0E08, IsPacked = true }, + new PackedEntry { Name = "tidu05.ma2", Offset = 0x67788, UnpackedSize = 0x8EA0, Size = 0x107A, IsPacked = true }, + new PackedEntry { Name = "tita00.ma2", Offset = 0x68802, UnpackedSize = 0x4670, Size = 0x1055, IsPacked = true }, + new PackedEntry { Name = "tita01.ma2", Offset = 0x69857, UnpackedSize = 0x7820, Size = 0x984, IsPacked = true }, + new PackedEntry { Name = "tita02.ma2", Offset = 0x6A1DB, UnpackedSize = 0x7820, Size = 0x0A07, IsPacked = true }, + new PackedEntry { Name = "tita03.ma2", Offset = 0x6ABE2, UnpackedSize = 0x7820, Size = 0x967, IsPacked = true }, + new PackedEntry { Name = "tita04.ma2", Offset = 0x6B549, UnpackedSize = 0x7820, Size = 0x9D2, IsPacked = true }, + new PackedEntry { Name = "tita05.ma2", Offset = 0x6BF1B, UnpackedSize = 0x7820, Size = 0x917, IsPacked = true }, + new PackedEntry { Name = "tita06.ma2", Offset = 0x6C832, UnpackedSize = 0x7820, Size = 0x9EE, IsPacked = true }, + new PackedEntry { Name = "tita07.ma2", Offset = 0x6D220, UnpackedSize = 0x2F00, Size = 0x361, IsPacked = true }, + new PackedEntry { Name = "tori00.ma2", Offset = 0x6D581, UnpackedSize = 0x5FD4, Size = 0x1B21, IsPacked = true }, + new PackedEntry { Name = "tori01.ma2", Offset = 0x6F0A2, UnpackedSize = 0x0DCC, Size = 0x3A8, IsPacked = true }, + new PackedEntry { Name = "tori02.ma2", Offset = 0x6F44A, UnpackedSize = 0x0DCC, Size = 0x3F3, IsPacked = true }, + new PackedEntry { Name = "tori03.ma2", Offset = 0x6F83D, UnpackedSize = 0x0DCC, Size = 0x38E, IsPacked = true }, + new PackedEntry { Name = "tori04.ma2", Offset = 0x6FBCB, UnpackedSize = 0x0B10, Size = 0x1E2, IsPacked = true }, + new PackedEntry { Name = "tori05.ma2", Offset = 0x6FDAD, UnpackedSize = 0x1C40, Size = 0x4C6, IsPacked = true }, + new PackedEntry { Name = "tori06.ma2", Offset = 0x70273, UnpackedSize = 0x20F0, Size = 0x6CF, IsPacked = true }, + new PackedEntry { Name = "tori07.ma2", Offset = 0x70942, UnpackedSize = 0x0D40, Size = 0x2B5, IsPacked = true }, + new PackedEntry { Name = "tori08.ma2", Offset = 0x70BF7, UnpackedSize = 0x0B10, Size = 0x2B3, IsPacked = true }, + new PackedEntry { Name = "yama01.ma2", Offset = 0x70EAA, UnpackedSize = 0x1F60, Size = 0x65B, IsPacked = true }, + new PackedEntry { Name = "yama02.ma2", Offset = 0x71505, UnpackedSize = 0x9DF0, Size = 0x1C46, IsPacked = true }, + new PackedEntry { Name = "yama03.ma2", Offset = 0x7314B, UnpackedSize = 0x4FD0, Size = 0x8E0, IsPacked = true }, + new PackedEntry { Name = "yama04.ma2", Offset = 0x73A2B, UnpackedSize = 0x5DE0, Size = 0x0AF6, IsPacked = true }, + new PackedEntry { Name = "yama05.ma2", Offset = 0x74521, UnpackedSize = 0x6290, Size = 0x0F38, IsPacked = true }, + new PackedEntry { Name = "yama06.ma2", Offset = 0x75459, UnpackedSize = 0x2730, Size = 0x0A47, IsPacked = true }, + new PackedEntry { Name = "yujin.ma2", Offset = 0x75EA0, UnpackedSize = 0x20F0, Size = 0x701, IsPacked = true }, + new PackedEntry { Name = "yuru00.ma2", Offset = 0x765A1, UnpackedSize = 0x7D20, Size = 0x1DCD, IsPacked = true }, + new PackedEntry { Name = "yuru01.ma2", Offset = 0x7836E, UnpackedSize = 0x159C, Size = 0x51D, IsPacked = true }, + new PackedEntry { Name = "yuru02.ma2", Offset = 0x7888B, UnpackedSize = 0x1376, Size = 0x4B3, IsPacked = true }, + new PackedEntry { Name = "yuru03.ma2", Offset = 0x78D3E, UnpackedSize = 0x1880, Size = 0x4B3, IsPacked = true }, + new PackedEntry { Name = "yuru04.ma2", Offset = 0x791F1, UnpackedSize = 0x159C, Size = 0x4BC, IsPacked = true }, + new PackedEntry { Name = "yuru05.ma2", Offset = 0x796AD, UnpackedSize = 0x2280, Size = 0x7F6, IsPacked = true }, + new PackedEntry { Name = "yuru06.ma2", Offset = 0x79EA3, UnpackedSize = 0x159C, Size = 0x4EA, IsPacked = true }, + new PackedEntry { Name = "yuru07.ma2", Offset = 0x7A38D, UnpackedSize = 0x2B18, Size = 0x85E, IsPacked = true }, + new PackedEntry { Name = "yuru08.ma2", Offset = 0x7ABEB, UnpackedSize = 0x3860, Size = 0x7E5, IsPacked = true }, + new PackedEntry { Name = "yuru09.ma2", Offset = 0x7B3D0, UnpackedSize = 0x2348, Size = 0x547, IsPacked = true }, + new PackedEntry { Name = "allmap.evt", Offset = 0x7B917, UnpackedSize = 0x11A, Size = 0x0FE, IsPacked = true }, + new PackedEntry { Name = "allmap2.evt", Offset = 0x7BA15, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "bukiya.evt", Offset = 0x7BA1B, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "cron00.evt", Offset = 0x7BA2B, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "cudu00.evt", Offset = 0x7BA3B, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu01.evt", Offset = 0x7BA73, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "cudu02.evt", Offset = 0x7BA8D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "cudu03.evt", Offset = 0x7BAA7, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu04.evt", Offset = 0x7BADF, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu05.evt", Offset = 0x7BB17, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "cudu06.evt", Offset = 0x7BB3B, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu07.evt", Offset = 0x7BB73, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu08.evt", Offset = 0x7BBAB, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "cudu09.evt", Offset = 0x7BBE3, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "cudu10.evt", Offset = 0x7BBF3, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "doguya.evt", Offset = 0x7BC0D, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "dokutu01.evt", Offset = 0x7BC1D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "dokutu02.evt", Offset = 0x7BC37, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "dokutu03.evt", Offset = 0x7BC47, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "dokutu04.evt", Offset = 0x7BC75, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "dokutu05.evt", Offset = 0x7BC8F, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "dokutu06.evt", Offset = 0x7BCA9, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "dokutu07.evt", Offset = 0x7BCCD, UnpackedSize = 0x34, Size = 0x31, IsPacked = true }, + new PackedEntry { Name = "dokutu08.evt", Offset = 0x7BCFE, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "dokutu09.evt", Offset = 0x7BD0E, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "flap00.evt", Offset = 0x7BD3C, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "flap01.evt", Offset = 0x7BD6A, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "flap02.evt", Offset = 0x7BDA2, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "flap03.evt", Offset = 0x7BDDA, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "flap04.evt", Offset = 0x7BE08, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "flap05.evt", Offset = 0x7BE2C, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "flap06.evt", Offset = 0x7BE64, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap07.evt", Offset = 0x7BE7E, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "flap08.evt", Offset = 0x7BECA, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap09.evt", Offset = 0x7BEE4, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "flap10.evt", Offset = 0x7BF30, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap11.evt", Offset = 0x7BF4A, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "flap12.evt", Offset = 0x7BF5A, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap13.evt", Offset = 0x7BF74, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap14.evt", Offset = 0x7BF8E, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "flap15.evt", Offset = 0x7BFA8, UnpackedSize = 0x34, Size = 0x30, IsPacked = true }, + new PackedEntry { Name = "flap16.evt", Offset = 0x7BFD8, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "flap17.evt", Offset = 0x7BFE8, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "flap18.evt", Offset = 0x7BFF8, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "fond00.evt", Offset = 0x7C012, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "fond01.evt", Offset = 0x7C040, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "fond02.evt", Offset = 0x7C064, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "fond03.evt", Offset = 0x7C0A6, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "fond04.evt", Offset = 0x7C0D4, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "fond05.evt", Offset = 0x7C0F8, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "fond06.evt", Offset = 0x7C13A, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "fond07.evt", Offset = 0x7C15E, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "fond08.evt", Offset = 0x7C178, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "fond09.evt", Offset = 0x7C19C, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "garu01.evt", Offset = 0x7C1AC, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "garu02.evt", Offset = 0x7C1D0, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "garu03.evt", Offset = 0x7C1F4, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "garu04.evt", Offset = 0x7C218, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "garu05.evt", Offset = 0x7C23C, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "garu06.evt", Offset = 0x7C26A, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "garu07.evt", Offset = 0x7C298, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "garu08.evt", Offset = 0x7C2DA, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "garu09.evt", Offset = 0x7C2FE, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "garu10.evt", Offset = 0x7C32C, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "hbmura01.evt", Offset = 0x7C35A, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "isek00.evt", Offset = 0x7C3A6, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "isek01.evt", Offset = 0x7C3D4, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "isek02.evt", Offset = 0x7C402, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "isek03.evt", Offset = 0x7C444, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "isek04.evt", Offset = 0x7C47C, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "isek05.evt", Offset = 0x7C4B4, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "isek06.evt", Offset = 0x7C4F6, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "jobin.evt", Offset = 0x7C52E, UnpackedSize = 0x70, Size = 0x6F, IsPacked = true }, + new PackedEntry { Name = "jobuki.evt", Offset = 0x7C59D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "jodog.evt", Offset = 0x7C5B7, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "jofuka1.evt", Offset = 0x7C5C7, UnpackedSize = 0x8E, Size = 0x8B, IsPacked = true }, + new PackedEntry { Name = "jofuka2.evt", Offset = 0x7C652, UnpackedSize = 0x8E, Size = 0x8B, IsPacked = true }, + new PackedEntry { Name = "jofuka3.evt", Offset = 0x7C6DD, UnpackedSize = 0x66, Size = 0x6A, IsPacked = true }, + new PackedEntry { Name = "joido.evt", Offset = 0x7C747, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "joisya.evt", Offset = 0x7C761, UnpackedSize = 0x70, Size = 0x6F, IsPacked = true }, + new PackedEntry { Name = "jomin1.evt", Offset = 0x7C7D0, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "jomin2.evt", Offset = 0x7C7E0, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "jouka.evt", Offset = 0x7C7F0, UnpackedSize = 0x0AC, Size = 0x0A8, IsPacked = true }, + new PackedEntry { Name = "jouma.evt", Offset = 0x7C898, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "joyado1.evt", Offset = 0x7C8B2, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "joyado2.evt", Offset = 0x7C8D6, UnpackedSize = 0x2A, Size = 0x29, IsPacked = true }, + new PackedEntry { Name = "kain1.evt", Offset = 0x7C8FF, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kain2.evt", Offset = 0x7C919, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kaiz00.evt", Offset = 0x7C933, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "kaiz01.evt", Offset = 0x7C993, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "kaiz02.evt", Offset = 0x7C9A3, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kaiz03.evt", Offset = 0x7C9BD, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "kaiz04.evt", Offset = 0x7CA09, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "kaiz05.evt", Offset = 0x7CA41, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "kaiz06.evt", Offset = 0x7CA8D, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "kaiz07.evt", Offset = 0x7CAC5, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "katabuki.evt", Offset = 0x7CAE9, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "katadogu.evt", Offset = 0x7CB03, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "katamin1.evt", Offset = 0x7CB13, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "katamin2.evt", Offset = 0x7CB23, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "katamina.evt", Offset = 0x7CB33, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "katania.evt", Offset = 0x7CB61, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "kataryo1.evt", Offset = 0x7CBC1, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "kataryo2.evt", Offset = 0x7CBE5, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "katasou1.evt", Offset = 0x7CBFF, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "katasou2.evt", Offset = 0x7CC0F, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "katasyo.evt", Offset = 0x7CC33, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "katayad1.evt", Offset = 0x7CC43, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "katayad2.evt", Offset = 0x7CC5D, UnpackedSize = 0x3E, Size = 0x37, IsPacked = true }, + new PackedEntry { Name = "koro00.evt", Offset = 0x7CC94, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "koro01.evt", Offset = 0x7CCAE, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "koro02.evt", Offset = 0x7CCC8, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "koro03.evt", Offset = 0x7CCE2, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kuro00.evt", Offset = 0x7CCFC, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kuro01.evt", Offset = 0x7CD16, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kuro02.evt", Offset = 0x7CD30, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "kuro03.evt", Offset = 0x7CD4A, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last00.evt", Offset = 0x7CD64, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last01.evt", Offset = 0x7CD7E, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "last02.evt", Offset = 0x7CDAC, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last03.evt", Offset = 0x7CDD0, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last04.evt", Offset = 0x7CDF4, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last05.evt", Offset = 0x7CE18, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "last06.evt", Offset = 0x7CE46, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last07.evt", Offset = 0x7CE6A, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last08.evt", Offset = 0x7CE84, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last09.evt", Offset = 0x7CEA8, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last10.evt", Offset = 0x7CEC2, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last11.evt", Offset = 0x7CEE6, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last12.evt", Offset = 0x7CF0A, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last13.evt", Offset = 0x7CF24, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "last14.evt", Offset = 0x7CF5C, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last15.evt", Offset = 0x7CF80, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "last16.evt", Offset = 0x7CFB8, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "last17.evt", Offset = 0x7CFF0, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "last18.evt", Offset = 0x7D000, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "last19.evt", Offset = 0x7D024, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "last20.evt", Offset = 0x7D052, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last21.evt", Offset = 0x7D06C, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last22.evt", Offset = 0x7D086, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last23.evt", Offset = 0x7D0A0, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "last24.evt", Offset = 0x7D0BA, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "matu00.evt", Offset = 0x7D0CA, UnpackedSize = 0x0AC, Size = 0x0A8, IsPacked = true }, + new PackedEntry { Name = "ojou01.evt", Offset = 0x7D172, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "ojou02.evt", Offset = 0x7D1AA, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "ojou03.evt", Offset = 0x7D1F6, UnpackedSize = 0x52, Size = 0x4A, IsPacked = true }, + new PackedEntry { Name = "ojou04.evt", Offset = 0x7D240, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "ojou05.evt", Offset = 0x7D264, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "ojou06.evt", Offset = 0x7D292, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "ojou07.evt", Offset = 0x7D2C0, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou08.evt", Offset = 0x7D2DA, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "ojou09.evt", Offset = 0x7D308, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou10.evt", Offset = 0x7D322, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou11.evt", Offset = 0x7D33C, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "ojou12.evt", Offset = 0x7D36A, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "ojou13.evt", Offset = 0x7D38E, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "ojou14.evt", Offset = 0x7D3BC, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou15.evt", Offset = 0x7D3D6, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "ojou16.evt", Offset = 0x7D422, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou17.evt", Offset = 0x7D43C, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou18.evt", Offset = 0x7D456, UnpackedSize = 0x3E, Size = 0x39, IsPacked = true }, + new PackedEntry { Name = "ojou19.evt", Offset = 0x7D48F, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "ojou20.evt", Offset = 0x7D4D1, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "ojou21.evt", Offset = 0x7D4EB, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "ojou22.evt", Offset = 0x7D50F, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "oldw00.evt", Offset = 0x7D529, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw01.evt", Offset = 0x7D539, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "oldw02.evt", Offset = 0x7D57B, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw03.evt", Offset = 0x7D58B, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw04.evt", Offset = 0x7D59B, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw05.evt", Offset = 0x7D5AB, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw06.evt", Offset = 0x7D5BB, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "oldw07.evt", Offset = 0x7D5F3, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw08.evt", Offset = 0x7D603, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw09.evt", Offset = 0x7D613, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "oldw10.evt", Offset = 0x7D623, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "oldw11.evt", Offset = 0x7D63D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "oldw12.evt", Offset = 0x7D657, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "omake.evt", Offset = 0x7D671, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "omake2.evt", Offset = 0x7D677, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "paremina.evt", Offset = 0x7D67D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "parerumo.evt", Offset = 0x7D697, UnpackedSize = 0x5C, Size = 0x58, IsPacked = true }, + new PackedEntry { Name = "pargil.evt", Offset = 0x7D6EF, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "parsaka.evt", Offset = 0x7D6FF, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "paruma.evt", Offset = 0x7D719, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "paryad1.evt", Offset = 0x7D733, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "paryad2.evt", Offset = 0x7D757, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "saba00.evt", Offset = 0x7D785, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "saba01.evt", Offset = 0x7D7D1, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "saba02.evt", Offset = 0x7D7FF, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "saba03.evt", Offset = 0x7D84B, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "saba04.evt", Offset = 0x7D8AB, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "sakaba.evt", Offset = 0x7D8ED, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "sepu.evt", Offset = 0x7D8FD, UnpackedSize = 0x48, Size = 0x47, IsPacked = true }, + new PackedEntry { Name = "sepu00.evt", Offset = 0x7D944, UnpackedSize = 0x48, Size = 0x47, IsPacked = true }, + new PackedEntry { Name = "sepu01.evt", Offset = 0x7D98B, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "sepu02.evt", Offset = 0x7D9A5, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "sepu03.evt", Offset = 0x7D9C9, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "sepu04.evt", Offset = 0x7D9D9, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "sepu05.evt", Offset = 0x7DA11, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "sepu06.evt", Offset = 0x7DA21, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "sepu07.evt", Offset = 0x7DA45, UnpackedSize = 0x48, Size = 0x4C, IsPacked = true }, + new PackedEntry { Name = "sepu08.evt", Offset = 0x7DA91, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "sepu09.evt", Offset = 0x7DAC9, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "sepu10.evt", Offset = 0x7DAED, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sepu11.evt", Offset = 0x7DB1B, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sepu12.evt", Offset = 0x7DB49, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sepu13.evt", Offset = 0x7DB77, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sepu14.evt", Offset = 0x7DBA5, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sima00.evt", Offset = 0x7DBD3, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "sima01.evt", Offset = 0x7DBED, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sima02.evt", Offset = 0x7DC1B, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sima03.evt", Offset = 0x7DC49, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sima04.evt", Offset = 0x7DC77, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "sima05.evt", Offset = 0x7DCA5, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "sima06.evt", Offset = 0x7DCDD, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "sima07.evt", Offset = 0x7DD01, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "sougen.evt", Offset = 0x7DD11, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "syoko01.evt", Offset = 0x7DD2B, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "syoko02.evt", Offset = 0x7DD59, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "syud00.evt", Offset = 0x7DD7D, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "syud01.evt", Offset = 0x7DD97, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "tidu00.evt", Offset = 0x7DDB1, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "tidu01.evt", Offset = 0x7DDD5, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "tidu02.evt", Offset = 0x7DE17, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "tidu03.evt", Offset = 0x7DE59, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "tidu04.evt", Offset = 0x7DE9B, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "tidu05.evt", Offset = 0x7DEDD, UnpackedSize = 0x3E, Size = 0x42, IsPacked = true }, + new PackedEntry { Name = "tita00.evt", Offset = 0x7DF1F, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "tita01.evt", Offset = 0x7DF39, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "tita02.evt", Offset = 0x7DF5D, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "tita03.evt", Offset = 0x7DF81, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "tita04.evt", Offset = 0x7DFAF, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "tita05.evt", Offset = 0x7DFDD, UnpackedSize = 0x34, Size = 0x38, IsPacked = true }, + new PackedEntry { Name = "tita06.evt", Offset = 0x7E015, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "tita07.evt", Offset = 0x7E043, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "tori00.evt", Offset = 0x7E05D, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "tori01.evt", Offset = 0x7E0BD, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "tori02.evt", Offset = 0x7E0CD, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "tori03.evt", Offset = 0x7E0DD, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "tori04.evt", Offset = 0x7E0ED, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "tori05.evt", Offset = 0x7E107, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "tori06.evt", Offset = 0x7E117, UnpackedSize = 0x34, Size = 0x33, IsPacked = true }, + new PackedEntry { Name = "tori07.evt", Offset = 0x7E14A, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "tori08.evt", Offset = 0x7E15A, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "yama01.evt", Offset = 0x7E16A, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "yama02.evt", Offset = 0x7E184, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "yama03.evt", Offset = 0x7E1A8, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "yama04.evt", Offset = 0x7E1CC, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "yama05.evt", Offset = 0x7E1FA, UnpackedSize = 0x2A, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "yama06.evt", Offset = 0x7E228, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "yujin.evt", Offset = 0x7E242, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "yuru00.evt", Offset = 0x7E252, UnpackedSize = 0x70, Size = 0x6A, IsPacked = true }, + new PackedEntry { Name = "yuru01.evt", Offset = 0x7E2BC, UnpackedSize = 0x20, Size = 0x24, IsPacked = true }, + new PackedEntry { Name = "yuru02.evt", Offset = 0x7E2E0, UnpackedSize = 0x70, Size = 0x74, IsPacked = true }, + new PackedEntry { Name = "yuru03.evt", Offset = 0x7E354, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "yuru04.evt", Offset = 0x7E36E, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "yuru05.evt", Offset = 0x7E37E, UnpackedSize = 0x0C, Size = 0x10, IsPacked = true }, + new PackedEntry { Name = "yuru06.evt", Offset = 0x7E38E, UnpackedSize = 0x8E, Size = 0x8B, IsPacked = true }, + new PackedEntry { Name = "yuru07.evt", Offset = 0x7E419, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "yuru08.evt", Offset = 0x7E479, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "yuru09.evt", Offset = 0x7E493, UnpackedSize = 0x16, Size = 0x1A, IsPacked = true }, + new PackedEntry { Name = "allmap.ts2", Offset = 0x7E4AD, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "allmap2.ts2", Offset = 0x7E4C5, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "bukiya.ts2", Offset = 0x7E4CB, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "cron00.ts2", Offset = 0x7E4F5, UnpackedSize = 0x122, Size = 0x0C1, IsPacked = true }, + new PackedEntry { Name = "cudu00.ts2", Offset = 0x7E5B6, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu01.ts2", Offset = 0x7E5BC, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu02.ts2", Offset = 0x7E5C2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu03.ts2", Offset = 0x7E5C8, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "cudu04.ts2", Offset = 0x7E5E0, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "cudu05.ts2", Offset = 0x7E5F8, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "cudu06.ts2", Offset = 0x7E610, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu07.ts2", Offset = 0x7E616, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "cudu08.ts2", Offset = 0x7E62E, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu09.ts2", Offset = 0x7E634, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "cudu10.ts2", Offset = 0x7E63A, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "doguya.ts2", Offset = 0x7E640, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "dokutu01.ts2", Offset = 0x7E658, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "dokutu02.ts2", Offset = 0x7E65E, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "dokutu03.ts2", Offset = 0x7E676, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "dokutu04.ts2", Offset = 0x7E67C, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "dokutu05.ts2", Offset = 0x7E682, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "dokutu06.ts2", Offset = 0x7E688, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "dokutu07.ts2", Offset = 0x7E68E, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "dokutu08.ts2", Offset = 0x7E6A6, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "dokutu09.ts2", Offset = 0x7E6BE, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap00.ts2", Offset = 0x7E6C4, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap01.ts2", Offset = 0x7E6CA, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "flap02.ts2", Offset = 0x7E6E2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap03.ts2", Offset = 0x7E6E8, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap04.ts2", Offset = 0x7E6EE, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap05.ts2", Offset = 0x7E6F4, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "flap06.ts2", Offset = 0x7E70C, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "flap07.ts2", Offset = 0x7E724, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap08.ts2", Offset = 0x7E72A, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap09.ts2", Offset = 0x7E730, UnpackedSize = 0x0A4, Size = 0x91, IsPacked = true }, + new PackedEntry { Name = "flap10.ts2", Offset = 0x7E7C1, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "flap11.ts2", Offset = 0x7E7EB, UnpackedSize = 0x4A, Size = 0x46, IsPacked = true }, + new PackedEntry { Name = "flap12.ts2", Offset = 0x7E831, UnpackedSize = 0x4A, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "flap13.ts2", Offset = 0x7E87F, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap14.ts2", Offset = 0x7E885, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "flap15.ts2", Offset = 0x7E8AF, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "flap16.ts2", Offset = 0x7E8B5, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "flap17.ts2", Offset = 0x7E8DF, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "flap18.ts2", Offset = 0x7E91B, UnpackedSize = 0x6E, Size = 0x66, IsPacked = true }, + new PackedEntry { Name = "fond00.ts2", Offset = 0x7E981, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "fond01.ts2", Offset = 0x7E987, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "fond02.ts2", Offset = 0x7E98D, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "fond03.ts2", Offset = 0x7E993, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "fond04.ts2", Offset = 0x7E999, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "fond05.ts2", Offset = 0x7E9B1, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "fond06.ts2", Offset = 0x7E9B7, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "fond07.ts2", Offset = 0x7E9CF, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "fond08.ts2", Offset = 0x7E9E7, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "fond09.ts2", Offset = 0x7E9FF, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "garu01.ts2", Offset = 0x7EA29, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "garu02.ts2", Offset = 0x7EA41, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "garu03.ts2", Offset = 0x7EA47, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "garu04.ts2", Offset = 0x7EA4D, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "garu05.ts2", Offset = 0x7EA65, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "garu06.ts2", Offset = 0x7EA7D, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "garu07.ts2", Offset = 0x7EA83, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "garu08.ts2", Offset = 0x7EA89, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "garu09.ts2", Offset = 0x7EAA1, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "garu10.ts2", Offset = 0x7EAA7, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "hbmura01.ts2", Offset = 0x7EABF, UnpackedSize = 0x80, Size = 0x74, IsPacked = true }, + new PackedEntry { Name = "isek00.ts2", Offset = 0x7EB33, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "isek01.ts2", Offset = 0x7EB4B, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "isek02.ts2", Offset = 0x7EB75, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "isek03.ts2", Offset = 0x7EB7B, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "isek04.ts2", Offset = 0x7EB81, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "isek05.ts2", Offset = 0x7EBBD, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "isek06.ts2", Offset = 0x7EBC3, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "jobin.ts2", Offset = 0x7EBC9, UnpackedSize = 0x0B6, Size = 0x0A3, IsPacked = true }, + new PackedEntry { Name = "jobuki.ts2", Offset = 0x7EC6C, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "jodog.ts2", Offset = 0x7EC96, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "jofuka1.ts2", Offset = 0x7ECAE, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "jofuka2.ts2", Offset = 0x7ECC6, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "jofuka3.ts2", Offset = 0x7ECDE, UnpackedSize = 0x4A, Size = 0x45, IsPacked = true }, + new PackedEntry { Name = "joido.ts2", Offset = 0x7ED23, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "joisya.ts2", Offset = 0x7ED29, UnpackedSize = 0x5C, Size = 0x5B, IsPacked = true }, + new PackedEntry { Name = "jomin1.ts2", Offset = 0x7ED84, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "jomin2.ts2", Offset = 0x7EDC0, UnpackedSize = 0x5C, Size = 0x57, IsPacked = true }, + new PackedEntry { Name = "jouka.ts2", Offset = 0x7EE17, UnpackedSize = 0x1E8, Size = 0x186, IsPacked = true }, + new PackedEntry { Name = "jouma.ts2", Offset = 0x7EF9D, UnpackedSize = 0x38, Size = 0x31, IsPacked = true }, + new PackedEntry { Name = "joyado1.ts2", Offset = 0x7EFCE, UnpackedSize = 0x6E, Size = 0x62, IsPacked = true }, + new PackedEntry { Name = "joyado2.ts2", Offset = 0x7F030, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kain1.ts2", Offset = 0x7F036, UnpackedSize = 0x4A, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "kain2.ts2", Offset = 0x7F084, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "kaiz00.ts2", Offset = 0x7F09C, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kaiz01.ts2", Offset = 0x7F0A2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kaiz02.ts2", Offset = 0x7F0A8, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kaiz03.ts2", Offset = 0x7F0AE, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "kaiz04.ts2", Offset = 0x7F0D8, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "kaiz05.ts2", Offset = 0x7F102, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kaiz06.ts2", Offset = 0x7F108, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "kaiz07.ts2", Offset = 0x7F120, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "katabuki.ts2", Offset = 0x7F126, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "katadogu.ts2", Offset = 0x7F162, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "katamin1.ts2", Offset = 0x7F17A, UnpackedSize = 0x6E, Size = 0x6A, IsPacked = true }, + new PackedEntry { Name = "katamin2.ts2", Offset = 0x7F1E4, UnpackedSize = 0x5C, Size = 0x59, IsPacked = true }, + new PackedEntry { Name = "katamina.ts2", Offset = 0x7F23D, UnpackedSize = 0x0B6, Size = 0x0AA, IsPacked = true }, + new PackedEntry { Name = "katania.ts2", Offset = 0x7F2E7, UnpackedSize = 0x0B6, Size = 0x0AA, IsPacked = true }, + new PackedEntry { Name = "kataryo1.ts2", Offset = 0x7F391, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "kataryo2.ts2", Offset = 0x7F3BB, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "katasou1.ts2", Offset = 0x7F3D3, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "katasou2.ts2", Offset = 0x7F3D9, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "katasyo.ts2", Offset = 0x7F3DF, UnpackedSize = 0x38, Size = 0x36, IsPacked = true }, + new PackedEntry { Name = "katayad1.ts2", Offset = 0x7F415, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "katayad2.ts2", Offset = 0x7F451, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "koro00.ts2", Offset = 0x7F469, UnpackedSize = 0x38, Size = 0x34, IsPacked = true }, + new PackedEntry { Name = "koro01.ts2", Offset = 0x7F49D, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "koro02.ts2", Offset = 0x7F4C7, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "koro03.ts2", Offset = 0x7F4CD, UnpackedSize = 0x6E, Size = 0x62, IsPacked = true }, + new PackedEntry { Name = "kuro00.ts2", Offset = 0x7F52F, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kuro01.ts2", Offset = 0x7F535, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kuro02.ts2", Offset = 0x7F53B, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "kuro03.ts2", Offset = 0x7F541, UnpackedSize = 0x0DA, Size = 0x99, IsPacked = true }, + new PackedEntry { Name = "last00.ts2", Offset = 0x7F5DA, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last01.ts2", Offset = 0x7F5E0, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last02.ts2", Offset = 0x7F5E6, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last03.ts2", Offset = 0x7F5EC, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last04.ts2", Offset = 0x7F5F2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last05.ts2", Offset = 0x7F5F8, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "last06.ts2", Offset = 0x7F622, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "last07.ts2", Offset = 0x7F63A, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "last08.ts2", Offset = 0x7F652, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last09.ts2", Offset = 0x7F658, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last10.ts2", Offset = 0x7F65E, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last11.ts2", Offset = 0x7F664, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last12.ts2", Offset = 0x7F66A, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last13.ts2", Offset = 0x7F670, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last14.ts2", Offset = 0x7F676, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "last15.ts2", Offset = 0x7F68E, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last16.ts2", Offset = 0x7F694, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last17.ts2", Offset = 0x7F69A, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "last18.ts2", Offset = 0x7F6B2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last19.ts2", Offset = 0x7F6B8, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last20.ts2", Offset = 0x7F6BE, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last21.ts2", Offset = 0x7F6C4, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last22.ts2", Offset = 0x7F6CA, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last23.ts2", Offset = 0x7F6D0, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "last24.ts2", Offset = 0x7F6D6, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "matu00.ts2", Offset = 0x7F6DC, UnpackedSize = 0x1E8, Size = 0x186, IsPacked = true }, + new PackedEntry { Name = "ojou01.ts2", Offset = 0x7F862, UnpackedSize = 0x242, Size = 0x16B, IsPacked = true }, + new PackedEntry { Name = "ojou02.ts2", Offset = 0x7F9CD, UnpackedSize = 0x80, Size = 0x70, IsPacked = true }, + new PackedEntry { Name = "ojou03.ts2", Offset = 0x7FA3D, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "ojou04.ts2", Offset = 0x7FA79, UnpackedSize = 0x38, Size = 0x36, IsPacked = true }, + new PackedEntry { Name = "ojou05.ts2", Offset = 0x7FAAF, UnpackedSize = 0x80, Size = 0x5B, IsPacked = true }, + new PackedEntry { Name = "ojou06.ts2", Offset = 0x7FB0A, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou07.ts2", Offset = 0x7FB22, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou08.ts2", Offset = 0x7FB3A, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou09.ts2", Offset = 0x7FB40, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou10.ts2", Offset = 0x7FB46, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou11.ts2", Offset = 0x7FB4C, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou12.ts2", Offset = 0x7FB64, UnpackedSize = 0x26, Size = 0x25, IsPacked = true }, + new PackedEntry { Name = "ojou13.ts2", Offset = 0x7FB89, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou14.ts2", Offset = 0x7FBA1, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou15.ts2", Offset = 0x7FBA7, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou16.ts2", Offset = 0x7FBAD, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou17.ts2", Offset = 0x7FBB3, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou18.ts2", Offset = 0x7FBB9, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou19.ts2", Offset = 0x7FBBF, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "ojou20.ts2", Offset = 0x7FBC5, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou21.ts2", Offset = 0x7FBDD, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "ojou22.ts2", Offset = 0x7FBF5, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "oldw00.ts2", Offset = 0x7FBFB, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw01.ts2", Offset = 0x7FC13, UnpackedSize = 0x6E, Size = 0x64, IsPacked = true }, + new PackedEntry { Name = "oldw02.ts2", Offset = 0x7FC77, UnpackedSize = 0x38, Size = 0x2E, IsPacked = true }, + new PackedEntry { Name = "oldw03.ts2", Offset = 0x7FCA5, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw04.ts2", Offset = 0x7FCBD, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw05.ts2", Offset = 0x7FCD5, UnpackedSize = 0x5C, Size = 0x4D, IsPacked = true }, + new PackedEntry { Name = "oldw06.ts2", Offset = 0x7FD22, UnpackedSize = 0x6E, Size = 0x5E, IsPacked = true }, + new PackedEntry { Name = "oldw07.ts2", Offset = 0x7FD80, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw08.ts2", Offset = 0x7FD98, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "oldw09.ts2", Offset = 0x7FDD4, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw10.ts2", Offset = 0x7FDEC, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "oldw11.ts2", Offset = 0x7FE04, UnpackedSize = 0x92, Size = 0x50, IsPacked = true }, + new PackedEntry { Name = "oldw12.ts2", Offset = 0x7FE54, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "omake.ts2", Offset = 0x7FE5A, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "omake2.ts2", Offset = 0x7FE60, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "paremina.ts2", Offset = 0x7FE66, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "parerumo.ts2", Offset = 0x7FEA2, UnpackedSize = 0x1C4, Size = 0x185, IsPacked = true }, + new PackedEntry { Name = "pargil.ts2", Offset = 0x80027, UnpackedSize = 0x5C, Size = 0x55, IsPacked = true }, + new PackedEntry { Name = "parsaka.ts2", Offset = 0x8007C, UnpackedSize = 0x5C, Size = 0x55, IsPacked = true }, + new PackedEntry { Name = "paruma.ts2", Offset = 0x800D1, UnpackedSize = 0x38, Size = 0x2B, IsPacked = true }, + new PackedEntry { Name = "paryad1.ts2", Offset = 0x800FC, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "paryad2.ts2", Offset = 0x80138, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "saba00.ts2", Offset = 0x80150, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "saba01.ts2", Offset = 0x80156, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "saba02.ts2", Offset = 0x8015C, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "saba03.ts2", Offset = 0x80162, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "saba04.ts2", Offset = 0x8018C, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "sakaba.ts2", Offset = 0x801A4, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu.ts2", Offset = 0x801CE, UnpackedSize = 0x92, Size = 0x7B, IsPacked = true }, + new PackedEntry { Name = "sepu00.ts2", Offset = 0x80249, UnpackedSize = 0x92, Size = 0x7B, IsPacked = true }, + new PackedEntry { Name = "sepu01.ts2", Offset = 0x802C4, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu02.ts2", Offset = 0x802EE, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu03.ts2", Offset = 0x80318, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu04.ts2", Offset = 0x80342, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu05.ts2", Offset = 0x8036C, UnpackedSize = 0x0A4, Size = 0x76, IsPacked = true }, + new PackedEntry { Name = "sepu06.ts2", Offset = 0x803E2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu07.ts2", Offset = 0x803E8, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sepu08.ts2", Offset = 0x80412, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu09.ts2", Offset = 0x80418, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu10.ts2", Offset = 0x8041E, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu11.ts2", Offset = 0x80424, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu12.ts2", Offset = 0x8042A, UnpackedSize = 0x38, Size = 0x31, IsPacked = true }, + new PackedEntry { Name = "sepu13.ts2", Offset = 0x8045B, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sepu14.ts2", Offset = 0x80461, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sima00.ts2", Offset = 0x8048B, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sima01.ts2", Offset = 0x80491, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sima02.ts2", Offset = 0x80497, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "sima03.ts2", Offset = 0x804C1, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "sima04.ts2", Offset = 0x804D9, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sima05.ts2", Offset = 0x804DF, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "sima06.ts2", Offset = 0x804F7, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "sima07.ts2", Offset = 0x804FD, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "sougen.ts2", Offset = 0x80515, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "syoko01.ts2", Offset = 0x8051B, UnpackedSize = 0x0EC, Size = 0x0BC, IsPacked = true }, + new PackedEntry { Name = "syoko02.ts2", Offset = 0x805D7, UnpackedSize = 0x146, Size = 0x10D, IsPacked = true }, + new PackedEntry { Name = "syud00.ts2", Offset = 0x806E4, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "syud01.ts2", Offset = 0x806EA, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tidu00.ts2", Offset = 0x80702, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "tidu01.ts2", Offset = 0x8073E, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tidu02.ts2", Offset = 0x80744, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tidu03.ts2", Offset = 0x8074A, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tidu04.ts2", Offset = 0x80762, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tidu05.ts2", Offset = 0x8077A, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "tita00.ts2", Offset = 0x807A4, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tita01.ts2", Offset = 0x807AA, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tita02.ts2", Offset = 0x807C2, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tita03.ts2", Offset = 0x807C8, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tita04.ts2", Offset = 0x807CE, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "tita05.ts2", Offset = 0x807F8, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "tita06.ts2", Offset = 0x807FE, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "tita07.ts2", Offset = 0x80828, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tori00.ts2", Offset = 0x80840, UnpackedSize = 0x1A0, Size = 0x131, IsPacked = true }, + new PackedEntry { Name = "tori01.ts2", Offset = 0x80971, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tori02.ts2", Offset = 0x80989, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "tori03.ts2", Offset = 0x809B3, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "tori04.ts2", Offset = 0x809CB, UnpackedSize = 0x80, Size = 0x5A, IsPacked = true }, + new PackedEntry { Name = "tori05.ts2", Offset = 0x80A25, UnpackedSize = 0x4A, Size = 0x4E, IsPacked = true }, + new PackedEntry { Name = "tori06.ts2", Offset = 0x80A73, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "tori07.ts2", Offset = 0x80AAF, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "tori08.ts2", Offset = 0x80AD9, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "yama01.ts2", Offset = 0x80B03, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "yama02.ts2", Offset = 0x80B1B, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "yama03.ts2", Offset = 0x80B21, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "yama04.ts2", Offset = 0x80B39, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "yama05.ts2", Offset = 0x80B51, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "yama06.ts2", Offset = 0x80B69, UnpackedSize = 0x2, Size = 0x6, IsPacked = true }, + new PackedEntry { Name = "yujin.ts2", Offset = 0x80B6F, UnpackedSize = 0x6E, Size = 0x69, IsPacked = true }, + new PackedEntry { Name = "yuru00.ts2", Offset = 0x80BD8, UnpackedSize = 0x146, Size = 0x120, IsPacked = true }, + new PackedEntry { Name = "yuru01.ts2", Offset = 0x80CF8, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + new PackedEntry { Name = "yuru02.ts2", Offset = 0x80D22, UnpackedSize = 0x5C, Size = 0x4F, IsPacked = true }, + new PackedEntry { Name = "yuru03.ts2", Offset = 0x80D71, UnpackedSize = 0x38, Size = 0x30, IsPacked = true }, + new PackedEntry { Name = "yuru04.ts2", Offset = 0x80DA1, UnpackedSize = 0x38, Size = 0x3C, IsPacked = true }, + new PackedEntry { Name = "yuru05.ts2", Offset = 0x80DDD, UnpackedSize = 0x5C, Size = 0x60, IsPacked = true }, + new PackedEntry { Name = "yuru06.ts2", Offset = 0x80E3D, UnpackedSize = 0x14, Size = 0x18, IsPacked = true }, + new PackedEntry { Name = "yuru07.ts2", Offset = 0x80E55, UnpackedSize = 0x122, Size = 0x0BE, IsPacked = true }, + new PackedEntry { Name = "yuru08.ts2", Offset = 0x80F13, UnpackedSize = 0x0B6, Size = 0x80, IsPacked = true }, + new PackedEntry { Name = "yuru09.ts2", Offset = 0x80F93, UnpackedSize = 0x26, Size = 0x2A, IsPacked = true }, + } + }, + { + "ALLMCP.273", new List() { + new PackedEntry { Name = "Allmap.mcp", Offset = 0x0, UnpackedSize = 0x5F436, Size = 0x1C61A, IsPacked = true }, + new PackedEntry { Name = "Bukiya.mcp", Offset = 0x1C61A, UnpackedSize = 0x23436, Size = 0x7157, IsPacked = true }, + new PackedEntry { Name = "Cron00.mcp", Offset = 0x23771, UnpackedSize = 0x19436, Size = 0x4652, IsPacked = true }, + new PackedEntry { Name = "Cudu00.mcp", Offset = 0x27DC3, UnpackedSize = 0x14436, Size = 0x2893, IsPacked = true }, + new PackedEntry { Name = "Cudu01.mcp", Offset = 0x2A656, UnpackedSize = 0x14436, Size = 0x2522, IsPacked = true }, + new PackedEntry { Name = "Cudu02.mcp", Offset = 0x2CB78, UnpackedSize = 0x14436, Size = 0x2522, IsPacked = true }, + new PackedEntry { Name = "Cudu03.mcp", Offset = 0x2F09A, UnpackedSize = 0x14436, Size = 0x2F8E, IsPacked = true }, + new PackedEntry { Name = "Cudu04.mcp", Offset = 0x32028, UnpackedSize = 0x0F436, Size = 0x1C4F, IsPacked = true }, + new PackedEntry { Name = "Cudu05.mcp", Offset = 0x33C77, UnpackedSize = 0x1E436, Size = 0x3EBF, IsPacked = true }, + new PackedEntry { Name = "Cudu06.mcp", Offset = 0x37B36, UnpackedSize = 0x14436, Size = 0x29DA, IsPacked = true }, + new PackedEntry { Name = "Cudu07.mcp", Offset = 0x3A510, UnpackedSize = 0x28436, Size = 0x45EF, IsPacked = true }, + new PackedEntry { Name = "Cudu08.mcp", Offset = 0x3EAFF, UnpackedSize = 0x0F436, Size = 0x1677, IsPacked = true }, + new PackedEntry { Name = "Cudu09.mcp", Offset = 0x40176, UnpackedSize = 0x14436, Size = 0x27F0, IsPacked = true }, + new PackedEntry { Name = "Cudu10.mcp", Offset = 0x42966, UnpackedSize = 0x14436, Size = 0x249C, IsPacked = true }, + new PackedEntry { Name = "Doguya.mcp", Offset = 0x44E02, UnpackedSize = 0x23436, Size = 0x68FA, IsPacked = true }, + new PackedEntry { Name = "Dokutu01.mcp", Offset = 0x4B6FC, UnpackedSize = 0x32436, Size = 0x0C7C5, IsPacked = true }, + new PackedEntry { Name = "Dokutu02.mcp", Offset = 0x57EC1, UnpackedSize = 0x2D436, Size = 0x0BD41, IsPacked = true }, + new PackedEntry { Name = "Dokutu03.mcp", Offset = 0x63C02, UnpackedSize = 0x1E436, Size = 0x78BF, IsPacked = true }, + new PackedEntry { Name = "Dokutu04.mcp", Offset = 0x6B4C1, UnpackedSize = 0x37436, Size = 0x0EB23, IsPacked = true }, + new PackedEntry { Name = "Dokutu05.mcp", Offset = 0x79FE4, UnpackedSize = 0x1E436, Size = 0x7C91, IsPacked = true }, + new PackedEntry { Name = "Dokutu06.mcp", Offset = 0x81C75, UnpackedSize = 0x23436, Size = 0x81BA, IsPacked = true }, + new PackedEntry { Name = "Dokutu07.mcp", Offset = 0x89E2F, UnpackedSize = 0x32436, Size = 0x0AAE1, IsPacked = true }, + new PackedEntry { Name = "Dokutu08.mcp", Offset = 0x94910, UnpackedSize = 0x32436, Size = 0x0CA7E, IsPacked = true }, + new PackedEntry { Name = "Dokutu09.mcp", Offset = 0x0A138E, UnpackedSize = 0x32436, Size = 0x0C3CA, IsPacked = true }, + new PackedEntry { Name = "Flap00.mcp", Offset = 0x0AD758, UnpackedSize = 0x3C436, Size = 0x0F905, IsPacked = true }, + new PackedEntry { Name = "Flap01.mcp", Offset = 0x0BD05D, UnpackedSize = 0x1E436, Size = 0x6D8D, IsPacked = true }, + new PackedEntry { Name = "Flap02.mcp", Offset = 0x0C3DEA, UnpackedSize = 0x1E436, Size = 0x6F0E, IsPacked = true }, + new PackedEntry { Name = "Flap03.mcp", Offset = 0x0CACF8, UnpackedSize = 0x1E436, Size = 0x72C2, IsPacked = true }, + new PackedEntry { Name = "Flap04.mcp", Offset = 0x0D1FBA, UnpackedSize = 0x2D436, Size = 0x0ACA5, IsPacked = true }, + new PackedEntry { Name = "Flap05.mcp", Offset = 0x0DCC5F, UnpackedSize = 0x37436, Size = 0x0E7E9, IsPacked = true }, + new PackedEntry { Name = "Flap06.mcp", Offset = 0x0EB448, UnpackedSize = 0x28436, Size = 0x0A7A2, IsPacked = true }, + new PackedEntry { Name = "Flap07.mcp", Offset = 0x0F5BEA, UnpackedSize = 0x19436, Size = 0x6541, IsPacked = true }, + new PackedEntry { Name = "Flap08.mcp", Offset = 0x0FC12B, UnpackedSize = 0x32436, Size = 0x0CF11, IsPacked = true }, + new PackedEntry { Name = "Flap09.mcp", Offset = 0x10903C, UnpackedSize = 0x46436, Size = 0x0FE0D, IsPacked = true }, + new PackedEntry { Name = "Flap10.mcp", Offset = 0x118E49, UnpackedSize = 0x23436, Size = 0x5E95, IsPacked = true }, + new PackedEntry { Name = "Flap11.mcp", Offset = 0x11ECDE, UnpackedSize = 0x23436, Size = 0x5B5F, IsPacked = true }, + new PackedEntry { Name = "Flap12.mcp", Offset = 0x12483D, UnpackedSize = 0x32436, Size = 0x8E8F, IsPacked = true }, + new PackedEntry { Name = "Flap13.mcp", Offset = 0x12D6CC, UnpackedSize = 0x23436, Size = 0x6599, IsPacked = true }, + new PackedEntry { Name = "Flap14.mcp", Offset = 0x133C65, UnpackedSize = 0x23436, Size = 0x567D, IsPacked = true }, + new PackedEntry { Name = "Flap15.mcp", Offset = 0x1392E2, UnpackedSize = 0x1E436, Size = 0x4F19, IsPacked = true }, + new PackedEntry { Name = "Flap16.mcp", Offset = 0x13E1FB, UnpackedSize = 0x23436, Size = 0x5DC6, IsPacked = true }, + new PackedEntry { Name = "Flap17.mcp", Offset = 0x143FC1, UnpackedSize = 0x23436, Size = 0x619D, IsPacked = true }, + new PackedEntry { Name = "Flap18.mcp", Offset = 0x14A15E, UnpackedSize = 0x1E436, Size = 0x69F8, IsPacked = true }, + new PackedEntry { Name = "Fond00.mcp", Offset = 0x150B56, UnpackedSize = 0x14436, Size = 0x5074, IsPacked = true }, + new PackedEntry { Name = "Fond01.mcp", Offset = 0x155BCA, UnpackedSize = 0x0F436, Size = 0x42A3, IsPacked = true }, + new PackedEntry { Name = "Fond02.mcp", Offset = 0x159E6D, UnpackedSize = 0x0F436, Size = 0x4A95, IsPacked = true }, + new PackedEntry { Name = "Fond03.mcp", Offset = 0x15E902, UnpackedSize = 0x14436, Size = 0x5405, IsPacked = true }, + new PackedEntry { Name = "Fond04.mcp", Offset = 0x163D07, UnpackedSize = 0x14436, Size = 0x5FA0, IsPacked = true }, + new PackedEntry { Name = "Fond05.mcp", Offset = 0x169CA7, UnpackedSize = 0x0F436, Size = 0x42A4, IsPacked = true }, + new PackedEntry { Name = "Fond06.mcp", Offset = 0x16DF4B, UnpackedSize = 0x14436, Size = 0x5A9F, IsPacked = true }, + new PackedEntry { Name = "Fond07.mcp", Offset = 0x1739EA, UnpackedSize = 0x0F436, Size = 0x44ED, IsPacked = true }, + new PackedEntry { Name = "Fond08.mcp", Offset = 0x177ED7, UnpackedSize = 0x1E436, Size = 0x7F4E, IsPacked = true }, + new PackedEntry { Name = "Fond09.mcp", Offset = 0x17FE25, UnpackedSize = 0x23436, Size = 0x6073, IsPacked = true }, + new PackedEntry { Name = "Garu01.mcp", Offset = 0x185E98, UnpackedSize = 0x0F436, Size = 0x4740, IsPacked = true }, + new PackedEntry { Name = "Garu02.mcp", Offset = 0x18A5D8, UnpackedSize = 0x0F436, Size = 0x43E3, IsPacked = true }, + new PackedEntry { Name = "Garu03.mcp", Offset = 0x18E9BB, UnpackedSize = 0x0F436, Size = 0x3665, IsPacked = true }, + new PackedEntry { Name = "Garu04.mcp", Offset = 0x192020, UnpackedSize = 0x0A436, Size = 0x33FE, IsPacked = true }, + new PackedEntry { Name = "Garu05.mcp", Offset = 0x19541E, UnpackedSize = 0x0F436, Size = 0x4617, IsPacked = true }, + new PackedEntry { Name = "Garu06.mcp", Offset = 0x199A35, UnpackedSize = 0x14436, Size = 0x5E12, IsPacked = true }, + new PackedEntry { Name = "Garu07.mcp", Offset = 0x19F847, UnpackedSize = 0x0F436, Size = 0x38A8, IsPacked = true }, + new PackedEntry { Name = "Garu08.mcp", Offset = 0x1A30EF, UnpackedSize = 0x0F436, Size = 0x3861, IsPacked = true }, + new PackedEntry { Name = "Garu09.mcp", Offset = 0x1A6950, UnpackedSize = 0x0F436, Size = 0x4252, IsPacked = true }, + new PackedEntry { Name = "Garu10.mcp", Offset = 0x1AABA2, UnpackedSize = 0x0F436, Size = 0x3D95, IsPacked = true }, + new PackedEntry { Name = "Hbmura01.mcp", Offset = 0x1AE937, UnpackedSize = 0x46436, Size = 0x1228F, IsPacked = true }, + new PackedEntry { Name = "Isek00.mcp", Offset = 0x1C0BC6, UnpackedSize = 0x2D436, Size = 0x0ADCE, IsPacked = true }, + new PackedEntry { Name = "Isek01.mcp", Offset = 0x1CB994, UnpackedSize = 0x14436, Size = 0x2564, IsPacked = true }, + new PackedEntry { Name = "Isek02.mcp", Offset = 0x1CDEF8, UnpackedSize = 0x1E436, Size = 0x3563, IsPacked = true }, + new PackedEntry { Name = "Isek03.mcp", Offset = 0x1D145B, UnpackedSize = 0x2D436, Size = 0x7CC5, IsPacked = true }, + new PackedEntry { Name = "Isek04.mcp", Offset = 0x1D9120, UnpackedSize = 0x19436, Size = 0x29AB, IsPacked = true }, + new PackedEntry { Name = "Isek05.mcp", Offset = 0x1DBACB, UnpackedSize = 0x14436, Size = 0x23D0, IsPacked = true }, + new PackedEntry { Name = "Isek06.mcp", Offset = 0x1DDE9B, UnpackedSize = 0x2D436, Size = 0x6241, IsPacked = true }, + new PackedEntry { Name = "Jobin.mcp", Offset = 0x1E40DC, UnpackedSize = 0x19436, Size = 0x4180, IsPacked = true }, + new PackedEntry { Name = "Jobuki.mcp", Offset = 0x1E825C, UnpackedSize = 0x23436, Size = 0x6634, IsPacked = true }, + new PackedEntry { Name = "Jodog.mcp", Offset = 0x1EE890, UnpackedSize = 0x19436, Size = 0x481E, IsPacked = true }, + new PackedEntry { Name = "Jofuka1.mcp", Offset = 0x1F30AE, UnpackedSize = 0x1E436, Size = 0x42F2, IsPacked = true }, + new PackedEntry { Name = "Jofuka2.mcp", Offset = 0x1F73A0, UnpackedSize = 0x19436, Size = 0x4160, IsPacked = true }, + new PackedEntry { Name = "Jofuka3.mcp", Offset = 0x1FB500, UnpackedSize = 0x0F436, Size = 0x2531, IsPacked = true }, + new PackedEntry { Name = "Joido.mcp", Offset = 0x1FDA31, UnpackedSize = 0x0F436, Size = 0x3649, IsPacked = true }, + new PackedEntry { Name = "Joisya.mcp", Offset = 0x20107A, UnpackedSize = 0x2D436, Size = 0x7BF9, IsPacked = true }, + new PackedEntry { Name = "Jomin1.mcp", Offset = 0x208C73, UnpackedSize = 0x23436, Size = 0x5ADD, IsPacked = true }, + new PackedEntry { Name = "Jomin2.mcp", Offset = 0x20E750, UnpackedSize = 0x1E436, Size = 0x50C4, IsPacked = true }, + new PackedEntry { Name = "Jouka.mcp", Offset = 0x213814, UnpackedSize = 0x41436, Size = 0x11817, IsPacked = true }, + new PackedEntry { Name = "Jouma.mcp", Offset = 0x22502B, UnpackedSize = 0x2D436, Size = 0x8097, IsPacked = true }, + new PackedEntry { Name = "Joyado1.mcp", Offset = 0x22D0C2, UnpackedSize = 0x28436, Size = 0x5DC8, IsPacked = true }, + new PackedEntry { Name = "Joyado2.mcp", Offset = 0x232E8A, UnpackedSize = 0x1E436, Size = 0x4AD1, IsPacked = true }, + new PackedEntry { Name = "Kain1.mcp", Offset = 0x23795B, UnpackedSize = 0x37436, Size = 0x9E8A, IsPacked = true }, + new PackedEntry { Name = "Kain2.mcp", Offset = 0x2417E5, UnpackedSize = 0x32436, Size = 0x8B6E, IsPacked = true }, + new PackedEntry { Name = "Kaiz00.mcp", Offset = 0x24A353, UnpackedSize = 0x19436, Size = 0x4048, IsPacked = true }, + new PackedEntry { Name = "Kaiz01.mcp", Offset = 0x24E39B, UnpackedSize = 0x14436, Size = 0x3260, IsPacked = true }, + new PackedEntry { Name = "Kaiz02.mcp", Offset = 0x2515FB, UnpackedSize = 0x0F436, Size = 0x26AA, IsPacked = true }, + new PackedEntry { Name = "Kaiz03.mcp", Offset = 0x253CA5, UnpackedSize = 0x19436, Size = 0x4153, IsPacked = true }, + new PackedEntry { Name = "Kaiz04.mcp", Offset = 0x257DF8, UnpackedSize = 0x19436, Size = 0x3510, IsPacked = true }, + new PackedEntry { Name = "Kaiz05.mcp", Offset = 0x25B308, UnpackedSize = 0x19436, Size = 0x3601, IsPacked = true }, + new PackedEntry { Name = "Kaiz06.mcp", Offset = 0x25E909, UnpackedSize = 0x0F436, Size = 0x27CE, IsPacked = true }, + new PackedEntry { Name = "Kaiz07.mcp", Offset = 0x2610D7, UnpackedSize = 0x28436, Size = 0x9E51, IsPacked = true }, + new PackedEntry { Name = "Katabuki.mcp", Offset = 0x26AF28, UnpackedSize = 0x28436, Size = 0x6A79, IsPacked = true }, + new PackedEntry { Name = "Katadogu.mcp", Offset = 0x2719A1, UnpackedSize = 0x23436, Size = 0x59A9, IsPacked = true }, + new PackedEntry { Name = "Katamin1.mcp", Offset = 0x27734A, UnpackedSize = 0x23436, Size = 0x5F75, IsPacked = true }, + new PackedEntry { Name = "Katamin2.mcp", Offset = 0x27D2BF, UnpackedSize = 0x2D436, Size = 0x81D8, IsPacked = true }, + new PackedEntry { Name = "Katamina.mcp", Offset = 0x285497, UnpackedSize = 0x41436, Size = 0x0C628, IsPacked = true }, + new PackedEntry { Name = "Katania.mcp", Offset = 0x291ABF, UnpackedSize = 0x46436, Size = 0x12EE8, IsPacked = true }, + new PackedEntry { Name = "Kataryo1.mcp", Offset = 0x2A49A7, UnpackedSize = 0x28436, Size = 0x6C0A, IsPacked = true }, + new PackedEntry { Name = "Kataryo2.mcp", Offset = 0x2AB5B1, UnpackedSize = 0x32436, Size = 0x89D1, IsPacked = true }, + new PackedEntry { Name = "Katasou1.mcp", Offset = 0x2B3F82, UnpackedSize = 0x14436, Size = 0x2A01, IsPacked = true }, + new PackedEntry { Name = "Katasou2.mcp", Offset = 0x2B6983, UnpackedSize = 0x14436, Size = 0x3122, IsPacked = true }, + new PackedEntry { Name = "Katasyo.mcp", Offset = 0x2B9AA5, UnpackedSize = 0x28436, Size = 0x7EBC, IsPacked = true }, + new PackedEntry { Name = "Katayad1.mcp", Offset = 0x2C1961, UnpackedSize = 0x23436, Size = 0x6050, IsPacked = true }, + new PackedEntry { Name = "Katayad2.mcp", Offset = 0x2C79B1, UnpackedSize = 0x1E436, Size = 0x4F1D, IsPacked = true }, + new PackedEntry { Name = "Koro00.mcp", Offset = 0x2CC8CE, UnpackedSize = 0x23436, Size = 0x6B2E, IsPacked = true }, + new PackedEntry { Name = "Koro01.mcp", Offset = 0x2D33FC, UnpackedSize = 0x19436, Size = 0x5926, IsPacked = true }, + new PackedEntry { Name = "Koro02.mcp", Offset = 0x2D8D22, UnpackedSize = 0x14436, Size = 0x3B9D, IsPacked = true }, + new PackedEntry { Name = "Koro03.mcp", Offset = 0x2DC8BF, UnpackedSize = 0x28436, Size = 0x7C95, IsPacked = true }, + new PackedEntry { Name = "Kuro00.mcp", Offset = 0x2E4554, UnpackedSize = 0x23436, Size = 0x9D0A, IsPacked = true }, + new PackedEntry { Name = "Kuro01.mcp", Offset = 0x2EE25E, UnpackedSize = 0x32436, Size = 0x0CCE7, IsPacked = true }, + new PackedEntry { Name = "Kuro02.mcp", Offset = 0x2FAF45, UnpackedSize = 0x32436, Size = 0x0CE36, IsPacked = true }, + new PackedEntry { Name = "Kuro03.mcp", Offset = 0x307D7B, UnpackedSize = 0x41436, Size = 0x0F30A, IsPacked = true }, + new PackedEntry { Name = "Last00.mcp", Offset = 0x317085, UnpackedSize = 0x28436, Size = 0x0A99C, IsPacked = true }, + new PackedEntry { Name = "Last01.mcp", Offset = 0x321A21, UnpackedSize = 0x0F436, Size = 0x32D3, IsPacked = true }, + new PackedEntry { Name = "Last02.mcp", Offset = 0x324CF4, UnpackedSize = 0x0F436, Size = 0x2EAA, IsPacked = true }, + new PackedEntry { Name = "Last03.mcp", Offset = 0x327B9E, UnpackedSize = 0x0F436, Size = 0x2E77, IsPacked = true }, + new PackedEntry { Name = "Last04.mcp", Offset = 0x32AA15, UnpackedSize = 0x0F436, Size = 0x2EAA, IsPacked = true }, + new PackedEntry { Name = "Last05.mcp", Offset = 0x32D8BF, UnpackedSize = 0x0F436, Size = 0x33A3, IsPacked = true }, + new PackedEntry { Name = "Last06.mcp", Offset = 0x330C62, UnpackedSize = 0x0A436, Size = 0x2738, IsPacked = true }, + new PackedEntry { Name = "Last07.mcp", Offset = 0x33339A, UnpackedSize = 0x0A436, Size = 0x2644, IsPacked = true }, + new PackedEntry { Name = "Last08.mcp", Offset = 0x3359DE, UnpackedSize = 0x0F436, Size = 0x29FA, IsPacked = true }, + new PackedEntry { Name = "Last09.mcp", Offset = 0x3383D8, UnpackedSize = 0x0F436, Size = 0x29FA, IsPacked = true }, + new PackedEntry { Name = "Last10.mcp", Offset = 0x33ADD2, UnpackedSize = 0x0F436, Size = 0x2CA3, IsPacked = true }, + new PackedEntry { Name = "Last11.mcp", Offset = 0x33DA75, UnpackedSize = 0x28436, Size = 0x8A4A, IsPacked = true }, + new PackedEntry { Name = "Last12.mcp", Offset = 0x3464BF, UnpackedSize = 0x1E436, Size = 0x6B7E, IsPacked = true }, + new PackedEntry { Name = "Last13.mcp", Offset = 0x34D03D, UnpackedSize = 0x1E436, Size = 0x6CB9, IsPacked = true }, + new PackedEntry { Name = "Last14.mcp", Offset = 0x353CF6, UnpackedSize = 0x2D436, Size = 0x0C33E, IsPacked = true }, + new PackedEntry { Name = "Last15.mcp", Offset = 0x360034, UnpackedSize = 0x1E436, Size = 0x71E3, IsPacked = true }, + new PackedEntry { Name = "Last16.mcp", Offset = 0x367217, UnpackedSize = 0x32436, Size = 0x0CE2D, IsPacked = true }, + new PackedEntry { Name = "Last17.mcp", Offset = 0x374044, UnpackedSize = 0x19436, Size = 0x57E0, IsPacked = true }, + new PackedEntry { Name = "Last18.mcp", Offset = 0x379824, UnpackedSize = 0x2D436, Size = 0x0BB0F, IsPacked = true }, + new PackedEntry { Name = "Last19.mcp", Offset = 0x385333, UnpackedSize = 0x1E436, Size = 0x6C5E, IsPacked = true }, + new PackedEntry { Name = "Last20.mcp", Offset = 0x38BF91, UnpackedSize = 0x23436, Size = 0x9708, IsPacked = true }, + new PackedEntry { Name = "Last21.mcp", Offset = 0x395699, UnpackedSize = 0x32436, Size = 0x9AEE, IsPacked = true }, + new PackedEntry { Name = "Last22.mcp", Offset = 0x39F187, UnpackedSize = 0x37436, Size = 0x0AA8D, IsPacked = true }, + new PackedEntry { Name = "Last23.mcp", Offset = 0x3A9C14, UnpackedSize = 0x0F436, Size = 0x302C, IsPacked = true }, + new PackedEntry { Name = "Last24.mcp", Offset = 0x3ACC40, UnpackedSize = 0x37436, Size = 0x0A078, IsPacked = true }, + new PackedEntry { Name = "Matu00.mcp", Offset = 0x3B6CB8, UnpackedSize = 0x41436, Size = 0x11DBE, IsPacked = true }, + new PackedEntry { Name = "Ojou01.mcp", Offset = 0x3C8A76, UnpackedSize = 0x3C436, Size = 0x0CF45, IsPacked = true }, + new PackedEntry { Name = "Ojou02.mcp", Offset = 0x3D59BB, UnpackedSize = 0x28436, Size = 0x7CC1, IsPacked = true }, + new PackedEntry { Name = "Ojou03.mcp", Offset = 0x3DD67C, UnpackedSize = 0x46436, Size = 0x0FBCF, IsPacked = true }, + new PackedEntry { Name = "Ojou04.mcp", Offset = 0x3ED24B, UnpackedSize = 0x46436, Size = 0x0DEEC, IsPacked = true }, + new PackedEntry { Name = "Ojou05.mcp", Offset = 0x3FB137, UnpackedSize = 0x23436, Size = 0x662B, IsPacked = true }, + new PackedEntry { Name = "Ojou06.mcp", Offset = 0x401762, UnpackedSize = 0x1E436, Size = 0x5782, IsPacked = true }, + new PackedEntry { Name = "Ojou07.mcp", Offset = 0x406EE4, UnpackedSize = 0x1E436, Size = 0x5D2F, IsPacked = true }, + new PackedEntry { Name = "Ojou08.mcp", Offset = 0x40CC13, UnpackedSize = 0x19436, Size = 0x584C, IsPacked = true }, + new PackedEntry { Name = "Ojou09.mcp", Offset = 0x41245F, UnpackedSize = 0x23436, Size = 0x71DA, IsPacked = true }, + new PackedEntry { Name = "Ojou10.mcp", Offset = 0x419639, UnpackedSize = 0x23436, Size = 0x71DA, IsPacked = true }, + new PackedEntry { Name = "Ojou11.mcp", Offset = 0x420813, UnpackedSize = 0x23436, Size = 0x7261, IsPacked = true }, + new PackedEntry { Name = "Ojou12.mcp", Offset = 0x427A74, UnpackedSize = 0x14436, Size = 0x416B, IsPacked = true }, + new PackedEntry { Name = "Ojou13.mcp", Offset = 0x42BBDF, UnpackedSize = 0x14436, Size = 0x4A1F, IsPacked = true }, + new PackedEntry { Name = "Ojou14.mcp", Offset = 0x4305FE, UnpackedSize = 0x14436, Size = 0x27E4, IsPacked = true }, + new PackedEntry { Name = "Ojou15.mcp", Offset = 0x432DE2, UnpackedSize = 0x14436, Size = 0x47C5, IsPacked = true }, + new PackedEntry { Name = "Ojou16.mcp", Offset = 0x4375A7, UnpackedSize = 0x1E436, Size = 0x5C02, IsPacked = true }, + new PackedEntry { Name = "Ojou17.mcp", Offset = 0x43D1A9, UnpackedSize = 0x19436, Size = 0x5819, IsPacked = true }, + new PackedEntry { Name = "Ojou18.mcp", Offset = 0x4429C2, UnpackedSize = 0x1E436, Size = 0x5DE8, IsPacked = true }, + new PackedEntry { Name = "Ojou19.mcp", Offset = 0x4487AA, UnpackedSize = 0x1E436, Size = 0x619C, IsPacked = true }, + new PackedEntry { Name = "Ojou20.mcp", Offset = 0x44E946, UnpackedSize = 0x0F436, Size = 0x3818, IsPacked = true }, + new PackedEntry { Name = "Ojou21.mcp", Offset = 0x45215E, UnpackedSize = 0x1E436, Size = 0x5932, IsPacked = true }, + new PackedEntry { Name = "Ojou22.mcp", Offset = 0x457A90, UnpackedSize = 0x1E436, Size = 0x5C02, IsPacked = true }, + new PackedEntry { Name = "Oldw00.mcp", Offset = 0x45D692, UnpackedSize = 0x19436, Size = 0x3B5C, IsPacked = true }, + new PackedEntry { Name = "Oldw01.mcp", Offset = 0x4611EE, UnpackedSize = 0x32436, Size = 0x0C387, IsPacked = true }, + new PackedEntry { Name = "Oldw02.mcp", Offset = 0x46D575, UnpackedSize = 0x19436, Size = 0x4935, IsPacked = true }, + new PackedEntry { Name = "Oldw03.mcp", Offset = 0x471EAA, UnpackedSize = 0x14436, Size = 0x34E0, IsPacked = true }, + new PackedEntry { Name = "Oldw04.mcp", Offset = 0x47538A, UnpackedSize = 0x14436, Size = 0x393D, IsPacked = true }, + new PackedEntry { Name = "Oldw05.mcp", Offset = 0x478CC7, UnpackedSize = 0x14436, Size = 0x2EA2, IsPacked = true }, + new PackedEntry { Name = "Oldw06.mcp", Offset = 0x47BB69, UnpackedSize = 0x2D436, Size = 0x0A85A, IsPacked = true }, + new PackedEntry { Name = "Oldw07.mcp", Offset = 0x4863C3, UnpackedSize = 0x19436, Size = 0x3994, IsPacked = true }, + new PackedEntry { Name = "Oldw08.mcp", Offset = 0x489D57, UnpackedSize = 0x19436, Size = 0x4663, IsPacked = true }, + new PackedEntry { Name = "Oldw09.mcp", Offset = 0x48E3BA, UnpackedSize = 0x19436, Size = 0x3EA6, IsPacked = true }, + new PackedEntry { Name = "Oldw10.mcp", Offset = 0x492260, UnpackedSize = 0x1E436, Size = 0x3C7F, IsPacked = true }, + new PackedEntry { Name = "Oldw11.mcp", Offset = 0x495EDF, UnpackedSize = 0x19436, Size = 0x264F, IsPacked = true }, + new PackedEntry { Name = "Oldw12.mcp", Offset = 0x49852E, UnpackedSize = 0x28436, Size = 0x0BC6C, IsPacked = true }, + new PackedEntry { Name = "Omake.mcp", Offset = 0x4A419A, UnpackedSize = 0x23436, Size = 0x638B, IsPacked = true }, + new PackedEntry { Name = "Omake2.mcp", Offset = 0x4AA525, UnpackedSize = 0x19436, Size = 0x4775, IsPacked = true }, + new PackedEntry { Name = "Paremina.mcp", Offset = 0x4AEC9A, UnpackedSize = 0x2D436, Size = 0x7E22, IsPacked = true }, + new PackedEntry { Name = "Parerumo.mcp", Offset = 0x4B6ABC, UnpackedSize = 0x46436, Size = 0x1178A, IsPacked = true }, + new PackedEntry { Name = "Pargil.mcp", Offset = 0x4C8246, UnpackedSize = 0x1E436, Size = 0x5710, IsPacked = true }, + new PackedEntry { Name = "Parsaka.mcp", Offset = 0x4CD956, UnpackedSize = 0x1E436, Size = 0x5054, IsPacked = true }, + new PackedEntry { Name = "Paruma.mcp", Offset = 0x4D29AA, UnpackedSize = 0x2D436, Size = 0x8097, IsPacked = true }, + new PackedEntry { Name = "Paryad1.mcp", Offset = 0x4DAA41, UnpackedSize = 0x23436, Size = 0x55C8, IsPacked = true }, + new PackedEntry { Name = "Paryad2.mcp", Offset = 0x4E0009, UnpackedSize = 0x1E436, Size = 0x4B6B, IsPacked = true }, + new PackedEntry { Name = "Saba00.mcp", Offset = 0x4E4B74, UnpackedSize = 0x19436, Size = 0x59AE, IsPacked = true }, + new PackedEntry { Name = "Saba01.mcp", Offset = 0x4EA522, UnpackedSize = 0x14436, Size = 0x4715, IsPacked = true }, + new PackedEntry { Name = "Saba02.mcp", Offset = 0x4EEC37, UnpackedSize = 0x19436, Size = 0x5C8A, IsPacked = true }, + new PackedEntry { Name = "Saba03.mcp", Offset = 0x4F48C1, UnpackedSize = 0x19436, Size = 0x4EAD, IsPacked = true }, + new PackedEntry { Name = "Saba04.mcp", Offset = 0x4F976E, UnpackedSize = 0x14436, Size = 0x430B, IsPacked = true }, + new PackedEntry { Name = "Sakaba.mcp", Offset = 0x4FDA79, UnpackedSize = 0x2D436, Size = 0x8231, IsPacked = true }, + new PackedEntry { Name = "Sepu00.mcp", Offset = 0x505CAA, UnpackedSize = 0x46436, Size = 0x0FB50, IsPacked = true }, + new PackedEntry { Name = "Sepu01.mcp", Offset = 0x5157FA, UnpackedSize = 0x14436, Size = 0x3950, IsPacked = true }, + new PackedEntry { Name = "Sepu02.mcp", Offset = 0x51914A, UnpackedSize = 0x14436, Size = 0x3B7D, IsPacked = true }, + new PackedEntry { Name = "Sepu03.mcp", Offset = 0x51CCC7, UnpackedSize = 0x19436, Size = 0x3E88, IsPacked = true }, + new PackedEntry { Name = "Sepu04.mcp", Offset = 0x520B4F, UnpackedSize = 0x19436, Size = 0x3B13, IsPacked = true }, + new PackedEntry { Name = "Sepu05.mcp", Offset = 0x524662, UnpackedSize = 0x23436, Size = 0x6BED, IsPacked = true }, + new PackedEntry { Name = "Sepu06.mcp", Offset = 0x52B24F, UnpackedSize = 0x19436, Size = 0x3745, IsPacked = true }, + new PackedEntry { Name = "Sepu07.mcp", Offset = 0x52E994, UnpackedSize = 0x1E436, Size = 0x42AA, IsPacked = true }, + new PackedEntry { Name = "Sepu08.mcp", Offset = 0x532C3E, UnpackedSize = 0x19436, Size = 0x3E45, IsPacked = true }, + new PackedEntry { Name = "Sepu09.mcp", Offset = 0x536A83, UnpackedSize = 0x1E436, Size = 0x56CA, IsPacked = true }, + new PackedEntry { Name = "Sepu10.mcp", Offset = 0x53C14D, UnpackedSize = 0x19436, Size = 0x4B66, IsPacked = true }, + new PackedEntry { Name = "Sepu11.mcp", Offset = 0x540CB3, UnpackedSize = 0x14436, Size = 0x4163, IsPacked = true }, + new PackedEntry { Name = "Sepu12.mcp", Offset = 0x544E16, UnpackedSize = 0x23436, Size = 0x690B, IsPacked = true }, + new PackedEntry { Name = "Sepu13.mcp", Offset = 0x54B721, UnpackedSize = 0x14436, Size = 0x415F, IsPacked = true }, + new PackedEntry { Name = "Sepu14.mcp", Offset = 0x54F880, UnpackedSize = 0x1E436, Size = 0x5A52, IsPacked = true }, + new PackedEntry { Name = "Sima00.mcp", Offset = 0x5552D2, UnpackedSize = 0x23436, Size = 0x9D0A, IsPacked = true }, + new PackedEntry { Name = "Sima01.mcp", Offset = 0x55EFDC, UnpackedSize = 0x19436, Size = 0x3E60, IsPacked = true }, + new PackedEntry { Name = "Sima02.mcp", Offset = 0x562E3C, UnpackedSize = 0x19436, Size = 0x3BDD, IsPacked = true }, + new PackedEntry { Name = "Sima03.mcp", Offset = 0x566A19, UnpackedSize = 0x1E436, Size = 0x4B47, IsPacked = true }, + new PackedEntry { Name = "Sima04.mcp", Offset = 0x56B560, UnpackedSize = 0x1E436, Size = 0x4283, IsPacked = true }, + new PackedEntry { Name = "Sima05.mcp", Offset = 0x56F7E3, UnpackedSize = 0x1E436, Size = 0x489C, IsPacked = true }, + new PackedEntry { Name = "Sima06.mcp", Offset = 0x57407F, UnpackedSize = 0x19436, Size = 0x3BFD, IsPacked = true }, + new PackedEntry { Name = "Sima07.mcp", Offset = 0x577C7C, UnpackedSize = 0x0A436, Size = 0x1C88, IsPacked = true }, + new PackedEntry { Name = "Sougen.mcp", Offset = 0x579904, UnpackedSize = 0x14436, Size = 0x61A0, IsPacked = true }, + new PackedEntry { Name = "Syoko01.mcp", Offset = 0x57FAA4, UnpackedSize = 0x41436, Size = 0x0B6AD, IsPacked = true }, + new PackedEntry { Name = "Syoko02.mcp", Offset = 0x58B151, UnpackedSize = 0x3C436, Size = 0x0A967, IsPacked = true }, + new PackedEntry { Name = "Syud00.mcp", Offset = 0x595AB8, UnpackedSize = 0x1E436, Size = 0x72AE, IsPacked = true }, + new PackedEntry { Name = "Syud01.mcp", Offset = 0x59CD66, UnpackedSize = 0x37436, Size = 0x9EF4, IsPacked = true }, + new PackedEntry { Name = "Tidu00.mcp", Offset = 0x5A6C5A, UnpackedSize = 0x23436, Size = 0x6DA2, IsPacked = true }, + new PackedEntry { Name = "Tidu01.mcp", Offset = 0x5AD9FC, UnpackedSize = 0x1E436, Size = 0x6F94, IsPacked = true }, + new PackedEntry { Name = "Tidu02.mcp", Offset = 0x5B4990, UnpackedSize = 0x1E436, Size = 0x78B8, IsPacked = true }, + new PackedEntry { Name = "Tidu03.mcp", Offset = 0x5BC248, UnpackedSize = 0x1E436, Size = 0x742F, IsPacked = true }, + new PackedEntry { Name = "Tidu04.mcp", Offset = 0x5C3677, UnpackedSize = 0x1E436, Size = 0x750F, IsPacked = true }, + new PackedEntry { Name = "Tidu05.mcp", Offset = 0x5CAB86, UnpackedSize = 0x1E436, Size = 0x723E, IsPacked = true }, + new PackedEntry { Name = "Tita00.mcp", Offset = 0x5D1DC4, UnpackedSize = 0x1E436, Size = 0x688B, IsPacked = true }, + new PackedEntry { Name = "Tita01.mcp", Offset = 0x5D864F, UnpackedSize = 0x0F436, Size = 0x3162, IsPacked = true }, + new PackedEntry { Name = "Tita02.mcp", Offset = 0x5DB7B1, UnpackedSize = 0x0F436, Size = 0x3128, IsPacked = true }, + new PackedEntry { Name = "Tita03.mcp", Offset = 0x5DE8D9, UnpackedSize = 0x0F436, Size = 0x3128, IsPacked = true }, + new PackedEntry { Name = "Tita04.mcp", Offset = 0x5E1A01, UnpackedSize = 0x0F436, Size = 0x31A0, IsPacked = true }, + new PackedEntry { Name = "Tita05.mcp", Offset = 0x5E4BA1, UnpackedSize = 0x0F436, Size = 0x31A0, IsPacked = true }, + new PackedEntry { Name = "Tita06.mcp", Offset = 0x5E7D41, UnpackedSize = 0x0F436, Size = 0x31B3, IsPacked = true }, + new PackedEntry { Name = "Tita07.mcp", Offset = 0x5EAEF4, UnpackedSize = 0x19436, Size = 0x3809, IsPacked = true }, + new PackedEntry { Name = "Tori00.mcp", Offset = 0x5EE6FD, UnpackedSize = 0x37436, Size = 0x0F315, IsPacked = true }, + new PackedEntry { Name = "Tori01.mcp", Offset = 0x5FDA12, UnpackedSize = 0x23436, Size = 0x6D20, IsPacked = true }, + new PackedEntry { Name = "Tori02.mcp", Offset = 0x604732, UnpackedSize = 0x28436, Size = 0x73D0, IsPacked = true }, + new PackedEntry { Name = "Tori03.mcp", Offset = 0x60BB02, UnpackedSize = 0x23436, Size = 0x68FA, IsPacked = true }, + new PackedEntry { Name = "Tori04.mcp", Offset = 0x6123FC, UnpackedSize = 0x14436, Size = 0x2882, IsPacked = true }, + new PackedEntry { Name = "Tori05.mcp", Offset = 0x614C7E, UnpackedSize = 0x28436, Size = 0x70F3, IsPacked = true }, + new PackedEntry { Name = "Tori06.mcp", Offset = 0x61BD71, UnpackedSize = 0x37436, Size = 0x947D, IsPacked = true }, + new PackedEntry { Name = "Tori07.mcp", Offset = 0x6251EE, UnpackedSize = 0x19436, Size = 0x4478, IsPacked = true }, + new PackedEntry { Name = "Tori08.mcp", Offset = 0x629666, UnpackedSize = 0x1E436, Size = 0x4CD1, IsPacked = true }, + new PackedEntry { Name = "Yama01.mcp", Offset = 0x62E337, UnpackedSize = 0x23436, Size = 0x9483, IsPacked = true }, + new PackedEntry { Name = "Yama02.mcp", Offset = 0x6377BA, UnpackedSize = 0x2D436, Size = 0x0BE5E, IsPacked = true }, + new PackedEntry { Name = "Yama03.mcp", Offset = 0x643618, UnpackedSize = 0x28436, Size = 0x92D5, IsPacked = true }, + new PackedEntry { Name = "Yama04.mcp", Offset = 0x64C8ED, UnpackedSize = 0x23436, Size = 0x85AF, IsPacked = true }, + new PackedEntry { Name = "Yama05.mcp", Offset = 0x654E9C, UnpackedSize = 0x23436, Size = 0x8927, IsPacked = true }, + new PackedEntry { Name = "Yama06.mcp", Offset = 0x65D7C3, UnpackedSize = 0x3C436, Size = 0x0D40C, IsPacked = true }, + new PackedEntry { Name = "Yujin.mcp", Offset = 0x66ABCF, UnpackedSize = 0x32436, Size = 0x9342, IsPacked = true }, + new PackedEntry { Name = "Yuru00.mcp", Offset = 0x673F11, UnpackedSize = 0x46436, Size = 0x11CB7, IsPacked = true }, + new PackedEntry { Name = "Yuru01.mcp", Offset = 0x685BC8, UnpackedSize = 0x28436, Size = 0x63B9, IsPacked = true }, + new PackedEntry { Name = "Yuru02.mcp", Offset = 0x68BF81, UnpackedSize = 0x23436, Size = 0x700A, IsPacked = true }, + new PackedEntry { Name = "Yuru03.mcp", Offset = 0x692F8B, UnpackedSize = 0x28436, Size = 0x7E6D, IsPacked = true }, + new PackedEntry { Name = "Yuru04.mcp", Offset = 0x69ADF8, UnpackedSize = 0x23436, Size = 0x6365, IsPacked = true }, + new PackedEntry { Name = "Yuru05.mcp", Offset = 0x6A115D, UnpackedSize = 0x37436, Size = 0x9BCF, IsPacked = true }, + new PackedEntry { Name = "Yuru06.mcp", Offset = 0x6AAD2C, UnpackedSize = 0x28436, Size = 0x7C33, IsPacked = true }, + new PackedEntry { Name = "Yuru07.mcp", Offset = 0x6B295F, UnpackedSize = 0x28436, Size = 0x8999, IsPacked = true }, + new PackedEntry { Name = "Yuru08.mcp", Offset = 0x6BB2F8, UnpackedSize = 0x28436, Size = 0x6847, IsPacked = true }, + new PackedEntry { Name = "Yuru09.mcp", Offset = 0x6C1B3F, UnpackedSize = 0x23436, Size = 0x6286, IsPacked = true }, + } + }, + }; + } +} diff --git a/Legacy/Herb/ArcPAK.cs b/Legacy/Herb/ArcPAK.cs new file mode 100644 index 00000000..add598dc --- /dev/null +++ b/Legacy/Herb/ArcPAK.cs @@ -0,0 +1,73 @@ +//! \file ArcPAK.cs +//! \date 2023 Aug 16 +//! \brief Herb Soft resource archive. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.Herb +{ + [Export(typeof(ArchiveFormat))] + public class PakOpener : ArchiveFormat + { + public override string Tag { get { return "PAK/HERB"; } } + public override string Description { get { return "Herb Soft resource archive"; } } + public override uint Signature { get { return 0x2E; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public PakOpener () + { + ContainedFormats = new[] { "GRP/HERB", "WAV", "TXT" }; + } + + public override ArcFile TryOpen (ArcView file) + { + long base_offset = 0x20000; + if (file.MaxOffset <= base_offset || !file.View.AsciiEqual (0x40, "..\0")) + return null; + long index_pos = 0x80; + var dir = new List(); + while (index_pos < base_offset && file.View.ReadByte (index_pos) != 0) + { + var name = file.View.ReadString (index_pos, 0x30); + var entry = Create (name); + entry.Offset = file.View.ReadUInt32 (index_pos + 0x30) + base_offset; + entry.Size = file.View.ReadUInt32 (index_pos + 0x38); + if (entry.Size != 0) + { + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + index_pos += 0x40; + } + if (dir.Count == 0) + return null; + return new ArcFile (file, this, dir); + } + } +} diff --git a/Legacy/Herb/ImageGRP.cs b/Legacy/Herb/ImageGRP.cs new file mode 100644 index 00000000..bb801c0f --- /dev/null +++ b/Legacy/Herb/ImageGRP.cs @@ -0,0 +1,91 @@ +//! \file ImageGRP.cs +//! \date 2023 Aug 16 +//! \brief Herb Soft compressed image format. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Compression; +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Herb +{ + internal class GrpMetaData : ImageMetaData + { + public int Stride; + } + + [Export(typeof(ImageFormat))] + public class GrpFormat : ImageFormat + { + public override string Tag { get { return "GRP/HERB"; } } + public override string Description { get { return "Herb Soft image format"; } } + public override uint Signature { get { return 0x08; } } + + public GrpFormat () + { + Signatures = new[] { 0x20u, 0x18u, 0x08u }; + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x28); + if (header.ToInt32 (4) != 0 || header.ToInt32 (8) != 1) + return null; + return new GrpMetaData { + Width = header.ToUInt32 (0x20), + Height = header.ToUInt32 (0x24), + BPP = header[0] == 0x08 ? 8 : header[0] == 0x18 ? 16 : 24, + Stride = header.ToInt32 (0x0C), + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (GrpMetaData)info; + BitmapPalette palette = null; + PixelFormat format = 8 == info.BPP ? PixelFormats.Indexed8 + : 16 == info.BPP ? PixelFormats.Bgr555 + : PixelFormats.Bgr24; + if (8 == info.BPP) + { + file.Position = 0x28; + palette = ReadPalette (file.AsStream, 0x100, PaletteFormat.RgbX); + } + int stride = meta.Stride; + var pixels = new byte[stride * info.iHeight]; + file.Position = 0x428; + using (var input = new ZLibStream (file.AsStream, CompressionMode.Decompress, true)) + { + input.Read (pixels, 0, pixels.Length); + } + return ImageData.Create (info, format, palette, pixels, stride); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("GrpFormat.Write not implemented"); + } + } +} diff --git a/Legacy/HyperWorks/ArcPAK.cs b/Legacy/HyperWorks/ArcPAK.cs new file mode 100644 index 00000000..a0c4e7bf --- /dev/null +++ b/Legacy/HyperWorks/ArcPAK.cs @@ -0,0 +1,71 @@ +//! \file ArcPAK.cs +//! \date 2022 May 28 +//! \brief HyperWorks resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.HyperWorks +{ + [Export(typeof(ArchiveFormat))] + public class PakOpener : ArchiveFormat + { + public override string Tag { get { return "PAK/ACE"; } } + public override string Description { get { return "HyperWorks resource archive"; } } + public override uint Signature { get { return 0x4B434150; } } // 'PACK' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + int index_size = file.View.ReadInt32 (4); + if (index_size >= file.MaxOffset - 4) + return null; + int count = index_size / 0x18; + if (!IsSaneCount (count)) + return null; + + uint pos = 8; + file.View.Reserve (pos, (uint)index_size); + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + uint name_length = file.View.ReadByte (pos+8); + if (name_length > 15) + return null; + var name = file.View.ReadString (pos+9, name_length); + var entry = Create (name); + entry.Offset = file.View.ReadUInt32 (pos); + entry.Size = file.View.ReadUInt32 (pos+4); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + pos += 0x18; + } + return new ArcFile (file, this, dir); + } + } +} diff --git a/Legacy/HyperWorks/ImageI24.cs b/Legacy/HyperWorks/ImageI24.cs index c31f660f..ea822005 100644 --- a/Legacy/HyperWorks/ImageI24.cs +++ b/Legacy/HyperWorks/ImageI24.cs @@ -23,10 +23,14 @@ // IN THE SOFTWARE. // +using GameRes.Utility; +using System; using System.ComponentModel.Composition; using System.IO; using System.Windows.Media; +// [980626][Love Gun] ACE OF SPADES 2 + namespace GameRes.Formats.HyperWorks { [Export(typeof(ImageFormat))] @@ -51,7 +55,8 @@ namespace GameRes.Formats.HyperWorks public override ImageData Read (IBinaryStream file, ImageMetaData info) { - return ImageData.Create (info, format, palette, pixels); + var reader = new I24Decoder (file, info); + return reader.Unpack(); } public override void Write (Stream file, ImageData image) @@ -59,4 +64,439 @@ namespace GameRes.Formats.HyperWorks throw new System.NotImplementedException ("I24Format.Write not implemented"); } } + + internal class I24Decoder + { + IBinaryStream m_input; + ImageMetaData m_info; + + public I24Decoder (IBinaryStream input, ImageMetaData info) + { + m_input = input; + m_info = info; + } + + static readonly short[] shiftTable = new short[] { + -1, 0, 0, 1, 1, 1, -1, 1, 2, 1, -2, 1, -2, 0, 0, 2, 1, 2, -1, 2, -3, 0 + }; + + bool cacheEmpty = true; + int byteCount = 0; + int bits = 0; + int bitCount = 0; + + class Node + { + public Node next; + public int depth; + public int token; + } + + struct DictRec + { + public Link link; + public int bitSize; + public int token; + } + + class Link + { + public Link[] children = new Link[2]; + public int token; + } + + DictRec[] dTable_1 = new DictRec[256]; + DictRec[] dTable_2 = new DictRec[256]; + DictRec[] dTable_3 = new DictRec[256]; + + Link[] tBuffer_1 = InitNodeList (684); + Link[] tBuffer_2 = InitNodeList (22); + Link[] tBuffer_3 = InitNodeList (502); + + Node[] bTable_1 = InitNodeList (342); + Node[] bTable_2 = InitNodeList (11); + Node[] bTable_3 = InitNodeList (251); + + static T[] InitNodeList(int count) where T : new() + { + var list = new T[count]; + for (int i = 0; i < count; ++i) + list[i] = new T(); + return list; + } + + public ImageData Unpack () + { + m_input.Position = 0x18; + int stride = m_info.iWidth * 4; + var pixels = new byte[stride * m_info.iHeight]; + byte[][] line_buffer = new[] { new byte[stride], new byte[stride], new byte[stride] }; + int dst = 0; + var shift_table = shiftTable.Clone() as short[]; + for (int y = 0; y < m_info.iHeight; ++y) + { + var line = line_buffer[2]; + line_buffer[2] = line_buffer[1]; + line_buffer[1] = line_buffer[0]; + line_buffer[0] = line; + int x = 0; + int p = 0; + while (x < m_info.iWidth) + { + if (byteCount-- == 0) + { + if (cacheEmpty) + { + cacheEmpty = false; + int val = ReadUInt8() << 8; + val |= ReadUInt8(); + bits = val; + bitCount = 8; + } + InitTree (bTable_1, 342); + InitTree (bTable_2, 11); + InitTree (bTable_3, 251); + + RebuildTree(bTable_1, dTable_1, tBuffer_1, 342); + RebuildTree(bTable_2, dTable_2, tBuffer_2, 11); + RebuildTree(bTable_3, dTable_3, tBuffer_3, 251); + byteCount = 0x3FFF; + } + int color_token = GetToken (dTable_1); + int shift_token = GetToken (dTable_2); + + int shift_idx = 2 * shift_token; + short s1 = shift_table[shift_idx]; + short s2 = shift_table[shift_idx + 1]; + if (shift_token != 0) + { + while (shift_token --> 0) + { + shift_table[shift_idx] = shift_table[shift_idx - 2]; + shift_table[shift_idx+1] = shift_table[shift_idx - 1]; + shift_idx -= 2; + } + shift_table[0] = s1; + shift_table[1] = s2; + } + int src = 4 * (x + s1); + if (color_token >= 216) + { + int count = color_token - 214; + x += count; + while (count --> 0) + { + line[p++] = line_buffer[s2][src++]; + line[p++] = line_buffer[s2][src++]; + line[p++] = line_buffer[s2][src++]; + line[p++] = line_buffer[s2][src++]; + } + } + else + { + sbyte r = shift_R[color_token]; + if (r == -3) + r = (sbyte)(GetToken (dTable_3) + 3); + line[p+2] = (byte)(line_buffer[s2][src+2] - r); + + sbyte g = shift_G[color_token]; + if (g == -3) + g = (sbyte)(GetToken(dTable_3) + 3); + line[p+1] = (byte)(line_buffer[s2][src+1] - g); + + sbyte b = shift_B[color_token]; + if (b == -3) + b = (sbyte)(GetToken(dTable_3) + 3); + line[p] = (byte)(line_buffer[s2][src] - b); + line[p+3] = 0; + p += 4; + ++x; + } + } + Buffer.BlockCopy (line_buffer[0], 0, pixels, dst, stride); + dst += stride; + } + return ImageData.Create (m_info, PixelFormats.Bgr32, null, pixels, stride); + } + + private void InitTree (Node[] tree, int count) // sub_408FB0 + { + for (int i = 0; i < count; ++i) + { + tree[i].next = null; + tree[i].depth = 0; + tree[i].token = i; + } + int length = GetBitLength(); + if (length <= 1) + return; + length -= 1; + int fieldWidth = GetBits (3); + int tIdx = 0; + while (length > 0) + { + if (GetNextBit() != 0) + { + tree[tIdx++].depth = GetBits (fieldWidth); + --length; + } + else + { + int step = GetBitLength(); + if (0 == step) + tIdx++; + else + tIdx += step; + } + } + } + + private void RebuildTree (Node[] tree, DictRec[] dict, Link[] links, int count) + { + for (int i = 0; i < 256; ++i) + { + dict[i].token = 0; + dict[i].link = null; + } + int next_idx = 0; // var node = tree; + count -= 1; + while (0 == tree[next_idx].depth) + { + if (--count <= 0) + break; + ++next_idx; + } + if (0 == count) + return; + + var node = tree[next_idx++]; + while (count --> 0) + { + int depth = tree[next_idx].depth; + if (depth != 0) + { + if (node != null) + { + if (node.depth <= depth) + { + var prev = node; + var ptr = node.next; + while (ptr != null) + { + if (ptr.depth > depth) + break; + prev = ptr; + ptr = ptr.next; + } + prev.next = tree[next_idx]; + tree[next_idx].next = ptr; + } + else + { + tree[next_idx].next = node; + node = tree[next_idx]; + } + } + } + ++next_idx; + } + + int bit_size = 0; + int t3_i = 0; + int dict_idx = 0; + while (node != null) + { + if (node.depth > bit_size) + { + dict_idx <<= node.depth - bit_size; + bit_size = node.depth; + } + if (bit_size >= 8) + { + if (bit_size == 8) + { + dict[dict_idx].bitSize = 8; + dict[dict_idx].token = node.token; + dict[dict_idx].link = null; + } + else + { + int d1 = bit_size - 8; + int d2 = dict_idx >> d1; + int d3 = dict_idx << (32 - (bit_size - 8)); + dict[d2].bitSize = 0; + var ptr_t2 = d2; // &dict[d2]; + var link = dict[ptr_t2].link; + if (null == link) + { + var t3_ptr = links[t3_i]; + t3_ptr.children[0] = null; + t3_ptr.children[1] = null; + t3_ptr.token = 0; + link = t3_ptr; + dict[ptr_t2].link = t3_ptr; + t3_i++; + } + while (d1 --> 0) + { + int v26 = (d3 >> 31) & 1; + d3 <<= 1; + if (null == link.children[v26]) + { + var t3_ptr = links[t3_i]; + t3_ptr.children[0] = null; + t3_ptr.children[1] = null; + t3_ptr.token = 0; + link.children[v26] = t3_ptr; + t3_i++; + } + link = link.children[v26]; + } + link.token = node.token; + } + } + else + { + int d1 = dict_idx << (8 - bit_size); + int d2 = 1 << (8 - bit_size); + while (d2 --> 0) + { + dict[d1].bitSize = bit_size; + dict[d1].token = node.token; + d1++; + } + } + ++dict_idx; + node = node.next; + } + } + + int GetToken (DictRec[] table) + { + var table_ptr = table[(bits >> 8) & 0xFF]; + int count = table_ptr.bitSize; + if (count != 0) + { + if (count >= bitCount) + { + bits <<= bitCount; + count -= bitCount; + bits |= ReadUInt8(); + bitCount = 8; + } + bits <<= count; + bitCount -= count; + return table_ptr.token; + } + else + { + bits = ReadUInt8() | bits << bitCount; + bits <<= 8 - bitCount; + Link link = table_ptr.link; + do + { + int path = GetNextBit() & 1; + link = link.children[path]; + if (null == link) + throw new InvalidFormatException ("Invalid tree path"); + } + while (link.children[0] != null); + return link.token; + } + } + + private byte ReadUInt8() + { + return (byte)m_input.ReadByte(); + } + + private int GetNextBit () + { + bits <<= 1; + if (0 == --bitCount) + { + bits |= ReadUInt8(); + bitCount = 8; + } + return (bits >> 16) & 1; + } + + private int GetBitLength () + { + if (GetNextBit() != 0) + return 0; + int i = 0; + do + { + ++i; + } + while (0 == GetNextBit()); + return (1 << i) | GetBits (i); + } + + private int GetBits (int count) + { + int n = count; + if (count >= bitCount) + { + bits <<= bitCount; + n = count - bitCount; + bits |= ReadUInt8(); + bitCount = 8; + } + if (n >= 8) + { + bits <<= 8; + bits |= ReadUInt8(); + n -= 8; + } + bits <<= n; + bitCount -= n; + return (bits >> 16) & bitMask[count]; + } + + static readonly int[] bitMask = new[] { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, + 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, + 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, + 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF + }; + + static readonly sbyte[] shift_R = new sbyte[] { + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + }; + static readonly sbyte[] shift_G = new sbyte[] { + -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -2, -2, -2, + -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, + -1, -1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, + -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, + -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + }; + static readonly sbyte[] shift_B = new sbyte[] { + -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, + -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, + 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, + -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, + -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, + 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, + -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, + -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, + 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, + -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, + }; + } } diff --git a/Legacy/James/ImageJMG.cs b/Legacy/James/ImageJMG.cs new file mode 100644 index 00000000..8f91c9e4 --- /dev/null +++ b/Legacy/James/ImageJMG.cs @@ -0,0 +1,133 @@ +//! \file ImageJMG.cs +//! \date 2022 Jun 11 +//! \brief JAMES engine encrypted image. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System.ComponentModel.Composition; +using System.IO; + +// [981105][Berserker] Situation +// [991109][Berserker] Situation 2 + +namespace GameRes.Formats.James +{ + public enum Obfuscation + { + None, + RotateWords, + ReverseBits + } + + public class JmgMetaData : ImageMetaData + { + public Obfuscation Method; + public ImageMetaData BmpInfo; + } + + [Export(typeof(ImageFormat))] + public class JmgFormat : ImageFormat + { + public override string Tag { get { return "JMG"; } } + public override string Description { get { return "JAMES engine obfuscated bitmap"; } } + public override uint Signature { get { return 0; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (2); + Obfuscation method; + if (header[0] == 0xD4 && header[1] == 0x24) + method = Obfuscation.RotateWords; + else if (header[0] == 0xB2 && header[1] == 0x42) + method = Obfuscation.ReverseBits; + else + return null; + using (var input = OpenAsBitmap (file, 0x40, method)) + { + var info = Bmp.ReadMetaData (input); + if (null == info) + return null; + return new JmgMetaData + { + Width = info.Width, + Height = info.Height, + BPP = info.BPP, + Method = method, + BmpInfo = info, + }; + } + } + + IBinaryStream OpenAsBitmap (IBinaryStream input, int length, Obfuscation method) + { + input.Position = 0; + var data = input.ReadBytes (length); + Deobfuscate (data, 0, length, method); + return new BinMemoryStream (data, input.Name); + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (JmgMetaData)info; + using (var bmp = OpenAsBitmap (file, (int)file.Length, meta.Method)) + return Bmp.Read (bmp, meta.BmpInfo); + } + + void Deobfuscate (byte[] data, int pos, int length, Obfuscation method) + { + switch (method) + { + case Obfuscation.RotateWords: RotateWords (data, pos, length); break; + case Obfuscation.ReverseBits: ReverseBits (data, pos, length); break; + } + } + + void RotateWords (byte[] data, int pos, int length) + { + for (int i = 0; i < length; i += 2) + { + ushort w = LittleEndian.ToUInt16 (data, pos+i); + w = (ushort)(w >> 12 | w << 4); + LittleEndian.Pack (w, data, pos+i); + } + } + + void ReverseBits (byte[] data, int pos, int length) + { + for (int i = 0; i < length; i += 2) + { + int v = LittleEndian.ToUInt16 (data, pos+i); + v = (v & 0xAAAA) >> 1 | (v & 0x5555) << 1; + v = (v & 0xCCCC) >> 2 | (v & 0x3333) << 2; + v = (v & 0xF0F0) >> 4 | (v & 0x0F0F) << 4; + v = (v & 0xFF00) >> 8 | (v & 0x00FF) << 8; + LittleEndian.Pack ((ushort)v, data, pos+i); + } + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("JmgFormat.Write not implemented"); + } + } +} diff --git a/Legacy/KApp/ArcASD.cs b/Legacy/KApp/ArcASD.cs index 44740d35..96a8a152 100644 --- a/Legacy/KApp/ArcASD.cs +++ b/Legacy/KApp/ArcASD.cs @@ -31,7 +31,7 @@ using System.IO; namespace GameRes.Formats.KApp { [Export(typeof(ArchiveFormat))] - public class AsdOpener : ArchiveFormat + public class AsdKToolOpener : ArchiveFormat { public override string Tag { get { return "ASD/KTOOL"; } } public override string Description { get { return "KApp engine resource archive"; } } @@ -122,4 +122,82 @@ namespace GameRes.Formats.KApp } } } + + internal class AsdArchive : ArcFile + { + public byte Format; + + public AsdArchive (ArcView arc, ArchiveFormat impl, ICollection dir) : base (arc, impl, dir) + { + } + } + + [Export(typeof(ArchiveFormat))] + public class AsdAudioOpener : ArchiveFormat + { + public override string Tag { get { return "ASD/SPIEL"; } } + public override string Description { get { return "Spiel audio archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + if (!file.Name.HasExtension (".asd")) + return null; + byte format = file.View.ReadByte (0); + if (format != 1 && format != 2) + return null; + var base_name = Path.GetFileNameWithoutExtension (file.Name); + uint index_pos = 0x10; + uint next_offset = file.View.ReadUInt32 (index_pos); + var dir = new List(); + while (next_offset != 0xFFFFFFFF) + { + index_pos += 4; + var entry = new Entry { + Name = string.Format ("{0}#{1:D4}", base_name, dir.Count), + Type = "audio", + Offset = next_offset, + }; + next_offset = file.View.ReadUInt32 (index_pos); + if (next_offset != 0xFFFFFFFF) + entry.Size = (uint)(next_offset - entry.Offset); + else + entry.Size = (uint)(file.MaxOffset - entry.Offset); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + if (0 == dir.Count) + return null; + return new AsdArchive (file, this, dir) { Format = format }; + } + + public override Stream OpenEntry (ArcFile a, Entry entry) + { + var arc = (AsdArchive)a; + var view = arc.File.View; + uint data_size = view.ReadUInt32 (entry.Offset); + if (2 == arc.Format) // MP3 + return arc.File.CreateStream (entry.Offset+0x10, data_size); + + var format = new WaveFormat { + FormatTag = view.ReadUInt16 (entry.Offset+8), + Channels = view.ReadUInt16 (entry.Offset+0xA), + SamplesPerSecond = view.ReadUInt32 (entry.Offset+0xC), + AverageBytesPerSecond = view.ReadUInt32 (entry.Offset+0x10), + BlockAlign = view.ReadUInt16 (entry.Offset+0x14), + BitsPerSample = view.ReadUInt16 (entry.Offset+0x16), + }; + byte[] header; + using (var riff = new MemoryStream()) + { + WaveAudio.WriteRiffHeader (riff, format, data_size); + header = riff.ToArray(); + } + var input = arc.File.CreateStream (entry.Offset+0x20, entry.Size-0x20); + return new PrefixStream (header, input); + } + } } diff --git a/Legacy/KApp/ArcCGD.cs b/Legacy/KApp/ArcCGD.cs new file mode 100644 index 00000000..28d68303 --- /dev/null +++ b/Legacy/KApp/ArcCGD.cs @@ -0,0 +1,94 @@ +//! \file ArcCGF.cs +//! \date 2022 May 06 +//! \brief Spiel image collection. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +// [001006][spiel] Koimusubi + +namespace GameRes.Formats.KApp +{ + internal class CgdEntry : Entry + { + public CgdMetaData Info; + } + + [Export(typeof(ArchiveFormat))] + public class CgdOpener : ArchiveFormat + { + public override string Tag { get { return "CGD/SPIEL"; } } + public override string Description { get { return "Spiel image collection"; } } + public override uint Signature { get { return 0x65697073; } } // 'spiel100' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + if (!file.View.AsciiEqual (0, "spiel100")) + return null; + int count = file.View.ReadInt32 (8); + if (!IsSaneCount (count)) + return null; + + var base_name = Path.GetFileNameWithoutExtension (file.Name); + uint index_pos = 0x10; + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + var entry = new CgdEntry { + Name = string.Format ("{0}#{1:D4}", base_name, i), + Type = "image", + Offset = file.View.ReadUInt32 (index_pos), + Size = file.View.ReadUInt32 (index_pos+4), + }; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + var info = entry.Info = new CgdMetaData { + Width = file.View.ReadUInt16 (index_pos+8), + Height = file.View.ReadUInt16 (index_pos+0xA), + BPP = file.View.ReadByte (index_pos+0xE), + DataOffset = 0, + Compression = file.View.ReadByte (index_pos+0xF), + RgbOrder = false, + }; + info.UnpackedSize = info.iWidth * info.iHeight * info.BPP / 8; + dir.Add (entry); + index_pos += 0x10; + } + return new ArcFile (file, this, dir); + } + + public override IImageDecoder OpenImage (ArcFile arc, Entry entry) + { + var cgent = entry as CgdEntry; + var input = arc.File.CreateStream (entry.Offset, entry.Size); + if (null == cgent) + return ImageFormatDecoder.Create (input); + return new CgdDecoder (input, cgent.Info); + } + } +} diff --git a/Legacy/KApp/ImageCGD.cs b/Legacy/KApp/ImageCGD.cs index ee1ea1e1..86ad9f8f 100644 --- a/Legacy/KApp/ImageCGD.cs +++ b/Legacy/KApp/ImageCGD.cs @@ -29,27 +29,23 @@ using System.IO; using System.Windows.Media; // [030228][spiel] The Black Box +// [001006][spiel] Koimusubi namespace GameRes.Formats.KApp { [Export(typeof(ImageFormat))] - public class CgdFormat : ImageFormat + public class CgdKToolFormat : ImageFormat { public override string Tag { get { return "CGD/KTOOL"; } } public override string Description { get { return "KApp compressed image format"; } } public override uint Signature { get { return 0x6F6F746B; } } // 'ktool210' - public CgdFormat () - { - Signatures = new uint[] { 0x6F6F746B, 0x65697073 }; - } - public override ImageMetaData ReadMetaData (IBinaryStream file) { var header = file.ReadHeader (0x18); if (header.ToInt32 (8) != 1) return null; - if (!header.AsciiEqual ("ktool210") && !header.AsciiEqual ("spiel100")) + if (!header.AsciiEqual ("ktool210")) return null; uint offset = header.ToUInt32 (0x10) & 0x7FFFFFFF; return CgdMetaData.FromStream (file, offset); @@ -67,11 +63,50 @@ namespace GameRes.Formats.KApp } } + [Export(typeof(ImageFormat))] + public class CgdSpielFormat : ImageFormat + { + public override string Tag { get { return "CGD/SPIEL"; } } + public override string Description { get { return "Spiel compressed image format"; } } + public override uint Signature { get { return 0x65697073; } } // 'spiel100' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x20); + if (header.ToInt32 (8) != 1) + return null; + if (!header.AsciiEqual ("spiel100")) + return null; + var info = new CgdMetaData { + Width = header.ToUInt16 (0x18), + Height = header.ToUInt16 (0x1A), + BPP = header[0x1E], + DataOffset = header.ToUInt32 (0x10), + Compression = header[0x1F], + RgbOrder = false, + }; + info.UnpackedSize = info.iWidth * info.iHeight * info.BPP / 8; + return info; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var reader = new CgdDecoder (file, (CgdMetaData)info); + return reader.Image; + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("CgdFormat.Write not implemented"); + } + } + internal class CgdMetaData : ImageMetaData { public uint DataOffset; public int UnpackedSize; public byte Compression; + public bool RgbOrder; internal static CgdMetaData FromStream (IBinaryStream file, uint offset) { @@ -93,6 +128,7 @@ namespace GameRes.Formats.KApp DataOffset = offset + 0x10 + header_size, UnpackedSize = unpacked_size, Compression = compression, + RgbOrder = bpp == 24, }; } } @@ -261,7 +297,9 @@ namespace GameRes.Formats.KApp m_input.Position = meta.DataOffset; var pixels = new byte[meta.UnpackedSize]; KTool.Unpack (m_input, pixels, meta.Compression); - PixelFormat format = 24 == meta.BPP ? PixelFormats.Rgb24 : PixelFormats.Bgra32; + PixelFormat format = 32 == meta.BPP ? PixelFormats.Bgra32 + : meta.RgbOrder ? PixelFormats.Rgb24 + : PixelFormats.Bgr24; return ImageData.Create (meta, format, null, pixels); } } diff --git a/Legacy/Legacy.csproj b/Legacy/Legacy.csproj index 56fc4ea6..86c05aad 100644 --- a/Legacy/Legacy.csproj +++ b/Legacy/Legacy.csproj @@ -44,9 +44,8 @@ true - - False - ..\packages\SharpZipLib.1.1.0\lib\net45\ICSharpCode.SharpZipLib.dll + + ..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll @@ -89,6 +88,11 @@ + + + + + @@ -101,10 +105,15 @@ + + + + + @@ -123,7 +132,10 @@ + + + @@ -178,7 +190,10 @@ + + + @@ -195,6 +210,8 @@ + + @@ -232,6 +249,7 @@ + @@ -275,7 +293,6 @@ - diff --git a/Legacy/Mink/ImageFC.cs b/Legacy/Mink/ImageFC.cs index 49308d05..81de7b7c 100644 --- a/Legacy/Mink/ImageFC.cs +++ b/Legacy/Mink/ImageFC.cs @@ -45,13 +45,17 @@ namespace GameRes.Formats.Mink public FcFormat () { - Signatures = new uint[] { 0x01184346, 0x00184346, 0x00204346, 0 }; + // 'Fc' is same as 'FC' but has checksum byte appended at the end + Signatures = new uint[] { + 0x00184346, 0x01184346, 0x00204346, 0x01204346, + 0x00186346, 0x01186346, 0x00206346, 0x01206346, + }; } public override ImageMetaData ReadMetaData (IBinaryStream file) { var header = file.ReadHeader (8); - if (!header.AsciiEqual ("FC")) + if (header[0] != 'F' || (header[1] & 0xDF) != 'C') return null; int bpp = header[2]; if (bpp != 24 && bpp != 32) @@ -103,6 +107,22 @@ namespace GameRes.Formats.Mink return ImageData.CreateFlipped (m_info, format, null, output, m_info.iWidth * 4); } + unsafe internal static bool Checksum (byte[] input) // for reference + { + int length = (input.Length - 1) / 4; + fixed (byte* data8 = &input[0]) + { + uint* data32 = (uint*)data8; + uint checksum = 0x8801; + for (int i = 0; i < length; ++i) + { + checksum += data32[i]; + } + byte sum = (byte)(checksum ^ (checksum >> 8) ^ (checksum >> 16) ^ (checksum >> 24)); + return input[input.Length-1] == sum; + } + } + void UnpackRgb (uint[] output) { int dst = 0; diff --git a/Legacy/Paprika/ArcPKDAT.cs b/Legacy/Paprika/ArcPKDAT.cs new file mode 100644 index 00000000..3ab5b84a --- /dev/null +++ b/Legacy/Paprika/ArcPKDAT.cs @@ -0,0 +1,98 @@ +//! \file ArcPKDAT.cs +//! \date 2022 Jun 26 +//! \brief Paprika resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.Paprika +{ + [Export(typeof(ArchiveFormat))] + public class PkDatOpener : ArchiveFormat + { + public override string Tag { get { return "DAT/PAPRIKA"; } } + public override string Description { get { return "Paprika resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + string[] KnownPkList = new[] { null, null, null, "PICPK", "AVIPK", "MUSPK", "WAVPK" }; + + public override ArcFile TryOpen (ArcView file) + { + var scn_name = VFS.ChangeFileName (file.Name, "SCNPK.DAT"); + if (!VFS.FileExists (scn_name)) + return null; + var arc_name = Path.GetFileName (file.Name).ToUpperInvariant(); + var base_name = Path.GetFileNameWithoutExtension (arc_name); + if (!char.IsDigit (base_name, base_name.Length - 1)) + return null; + int arcId; + for (arcId = 3; arcId < KnownPkList.Length; ++arcId) + { + if (KnownPkList[arcId] != null && arc_name.StartsWith (KnownPkList[arcId])) + break; + } + if (arcId == KnownPkList.Length) + return null; + int arc_num = base_name[base_name.Length-1] - '0'; + var base_ext = arc_name.Substring (0, 3); + using (var scn = VFS.OpenBinaryStream (scn_name)) + { + scn.Position = arcId * 4; + uint index_pos = scn.ReadUInt32(); + if (0 == index_pos) + return null; + scn.Position = index_pos; + var dir = new List(); + long last_offset = -1; + int i = 0; + while (scn.PeekByte() != -1) + { + ++i; + byte num = scn.ReadUInt8(); + long offset = scn.ReadUInt32(); + uint size = scn.ReadUInt32(); + if (num != arc_num) + continue; + if (offset < last_offset) + break; + var name = string.Format ("{0:D4}.{1}", i - 1, base_ext); + var entry = Create (name); + entry.Offset = offset; + entry.Size = size; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + last_offset = offset; + } + if (dir.Count == 0) + return null; + return new ArcFile (file, this, dir); + } + } + } +} diff --git a/Legacy/Paprika/ImageNP.cs b/Legacy/Paprika/ImageNP.cs new file mode 100644 index 00000000..784857e6 --- /dev/null +++ b/Legacy/Paprika/ImageNP.cs @@ -0,0 +1,412 @@ +//! \file ImageNP.cs +//! \date 2022 Jun 26 +//! \brief Paprika image format. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; +using System.Windows.Media; + +namespace GameRes.Formats.Paprika +{ + public class NpMetaData : ImageMetaData + { + public uint DataOffset; + } + + [Export(typeof(ImageFormat))] + public class NpFormat : ImageFormat + { + public override string Tag { get { return "PIC/NP"; } } + public override string Description { get { return "Paprika image format"; } } + public override uint Signature { get { return 0x0001504E; } } // 'NP' + + public NpFormat () + { + Signatures = new[] { 0x0001504Eu, 0u }; + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x10); + if (!header.AsciiEqual (0, "NP")) + return null; + int frame_count = header.ToUInt16 (2); + if (frame_count == 0) + return null; + return new NpMetaData { + Width = header.ToUInt32 (4), + Height = header.ToUInt32 (8), + BPP = 24, + DataOffset = header.ToUInt32 (12), + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var reader = new NpReader (file, (NpMetaData)info); + var pixels = reader.Unpack(); + return ImageData.Create (info, PixelFormats.Bgr24, null, pixels); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("NpFormat.Write not implemented"); + } + } + + internal class NpReader + { + IBinaryStream m_input; + NpMetaData m_info; + byte[] m_output; + + public NpReader (IBinaryStream input, NpMetaData info) + { + m_input = input; + m_info = info; + } + + int bitCount; + uint bits; + + static readonly int[] bitMap = new int[] { + 2, 0x00, 3, 0x04, 3, 0x0C, 4, 0x14, 4, 0x24, 4, 0x34, 4, 0x44, 4, 0x54, + 4, 0x64, 4, 0x74, 4, 0x84, 4, 0x94, 4, 0xA4, 5, 0xB4, 5, 0xD4, 5, 0xF4, + }; + + static readonly ushort[] wordList = new ushort[] { + 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, + 0x108, 0x109, 0x10A, 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, + 0x00, 0x20, 0x30, 0xFF, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, + 0x110, 0x111, + }; + + byte[] field_0 = new byte[0x10000]; + int field_4; + ushort[] field_8; + int[] field_C; + ushort[] field_8C; + + public byte[] Unpack () + { + m_input.Position = m_info.DataOffset; + int unpacked_size = m_input.ReadInt32(); + int packed_size = m_input.ReadInt32(); + m_output = new byte[unpacked_size]; + + field_4 = 0; + field_8 = new ushort[0x112]; + field_C = bitMap.Clone() as int[]; + field_8C = wordList.Clone() as ushort[]; + int dst = 0; + while (dst < unpacked_size && UnpackBits (ref dst)) + ; + var pixels = new byte[unpacked_size - 0x1C]; + Buffer.BlockCopy (m_output, 0x1C, pixels, 0, pixels.Length); + return pixels; + } + + ushort[] v74 = new ushort[0x225]; + + bool UnpackBits (ref int dst) + { + bitCount = 0; + while (m_input.PeekByte() != -1) + { + int v9 = GetBits (4) * 2; + int v12 = field_C[v9]; + int word; + if (0 == v12) + { + word = field_8C[field_C[v9 + 1]]; + } + else + { + int v17 = GetBits (v12) + field_C[v9 + 1]; + if (v17 >= 274) + return false; + word = field_8C[v17]; + } + ++field_8[word]; + int count = 0; + if (word < 256) + { + if (dst >= m_output.Length) + return false; + m_output[dst++] = (byte)word; + field_0[field_4++ & 0xFFFF] = (byte)word; + continue; + } + else if (word == 272) + { + sub_416E80 (v74); + int j = 0; + for (int i = 0; i < 0x112; ++i) + { + field_8C[i] = v74[j]; + j += 2; + } + int v22 = 0; + int v23 = 1; // &this->field_C[1]; + int v69 = 0; + for (int v65 = 16; v65 != 0; --v65) + { + int n; + for (n = 0; ; ++n) + { + int v26 = GetBits (1); + if (v26 != 0) + break; + } + v22 += n; + field_C[v23 - 1] = v22; + field_C[v23] = v69; + v23 += 2; + v69 += 1 << v22; + } + continue; + } + else if (word == 273) + { + return true; + } + else if (word < 264) + { + count = word - 256; + } + else + { + int v29 = dword_4257CC[2 * (word - 264)]; + int v31 = GetBits (v29); + count = v31 + dword_4257CC[2 * (word - 264) + 1]; + } + int v70 = GetBits (3); + int v64 = 0; + int v37 = dword_425810[2 * v70] + 9; + if (v37 > 8) + { + v37 -= 8; + int v39 = GetBits (8); + v64 = v39 << v37; + } + int v43 = GetBits (v37) | v64; + int v46 = (dword_425810[2 * v70 + 1] << 9) + v43; + count += 4; + int v45 = dst; // output; + int dst_next = dst + count + 4; // &output[count + 4]; + if (dst_next > m_output.Length) + break; + int src = field_4 - v46; + if (count >= v46) + { + int v49 = src & 0xFFFF; + int v51, v52; + if (v49 + v46 <= 0x10000) + { + v52 = v46; + v51 = v49; // &this->field_0[v49]; + } + else + { + int v50 = 0x10000 - (src & 0xFFFF); + Buffer.BlockCopy (field_0, src & 0xFFFF, m_output, dst, v50); +// qmemcpy(output, &this->field_0[src & 0xFFFF], v50); + v51 = 0; // this->field_0; + v52 = v46 - v50; + v45 += v50; // &output[v50]; + } + Buffer.BlockCopy (field_0, v51, m_output, v45, v52); +// qmemcpy(v45, v51, v52); + int v54 = count - v46; + if (v54 > 0) + { + Binary.CopyOverlapped (m_output, dst, dst + v46, v54); + /* + int v53 = 0; + int v55 = dst + v46; // &output[v46]; + do + { + m_output[v55 + v53] = m_output[dst + v53]; + ++v53; + } + while (v53 < v54); + */ + } + } + else if ((src & 0xFFFF) + count <= 0x10000) + { + Buffer.BlockCopy (field_0, src & 0xFFFF, m_output, dst, count); +// qmemcpy(output, &this->field_0[(unsigned __int16)src], count); + } + else + { + for (int i = 0; i < count; ++i) + { + m_output[dst + i] = field_0[(src + i) & 0xFFFF]; + } + } + /* + int v56 = field_4 & 0xFFFF; + if (v56 + count <= 0x10000) + { + v60 = output; + v59 = count; + v58 = &this->field_0[v56]; + } + else + { + v57 = 0x10000 - v56; + qmemcpy(&this->field_0[v56], output, 0x10000 - v56); + v58 = this->field_0; + v59 = count - v57; + v60 = &output[v57]; + } + qmemcpy(v58, v60, v59); + */ + for (int i = 0; i < count; ++i) + { + field_0[(field_4 + i) & 0xFFFF] = m_output[dst]; + } + dst = dst_next; + field_4 += count; + } + return false; + } + + int GetBits (int count) + { + if (bitCount < count) + { + bits |= (uint)m_input.ReadUInt8() << (24 - bitCount); + bitCount += 8; + } + uint b = bits >> (32 - count); + bits <<= count; + bitCount -= count; + return (int)b; + } + + int sub_416E80 (ushort[] a2) + { + int v2 = 0; // a2; + int v3 = 0; + ushort v4 = 0; + do + { + a2[v2] = v4; + a2[v2 + 1] = field_8[v4]; + v2 += 2; + v3 += field_8[v4]; + field_8[v4] >>= 1; + ++v4; + } + while (v4 < 0x112); + sub_416DC0 (a2, -2, 0x112); + return v3; + } + + byte[] dword0 = new byte[4]; + byte[] dword1 = new byte[4]; + + void sub_416DC0 (ushort[] w, int a1, int count) + { + int v2 = a1; + int v3 = count; + int v4 = 40; + do + { + int v5 = v4 + 1; + int v10 = v4 + 1; + if (v5 <= v3) + { + do + { + int v6 = 4 * v5; + int v9 = v5; +// v11 = *(_DWORD *)&v2[v6]; + Buffer.BlockCopy (w, v2 + v6, dword0, 0, 4); + if (v5 > v4) + { + int v7 = 4 * v4; + int v8; + do + { +// v8 = *(_WORD *)&v2[v6 - v7 + 2] - SHIWORD(v11); + Buffer.BlockCopy (w, v2 + v6 - v7, dword1, 0, 4); + v8 = LittleEndian.ToInt16 (dword1, 2) - LittleEndian.ToInt16 (dword0, 2); + if (v8 == 0) + { +// v8 = *(_WORD *)&v2[v6 - v7] - (signed __int16)v11; + v8 = LittleEndian.ToInt16 (dword1, 0) - LittleEndian.ToInt16 (dword0, 0); + } + if (v8 >= 0) + break; +// *(_DWORD *)&v2[v6] = *(_DWORD *)&v2[v6 - v7]; + Buffer.BlockCopy (w, v2 + v6 - v7, w, v2 + v6, 4); + v6 -= v7; + v9 -= v4; + } + while (v9 > v4); + v5 = v10; + } + ++v5; +// *(_DWORD *)&v2[4 * v9] = v11; + Buffer.BlockCopy (dword0, 0, w, v2 + v9 * 4, 4); + v3 = count; + v10 = v5; + } + while (v5 <= count); + } + v4 /= 3; + } + while (v4 > 0); + } + + static readonly int[] dword_425810 = new int[] { + 0, 0, 0, 1, 1, 2, 2, 4, 3, 8, 4, 0x10, 5, 0x20, 6, 0x40 + }; + static readonly int[] dword_4257CC = new int[] { + 1, 8, 2, 0x0A, 3, 0x0E, 4, 0x16, 5, 0x26, 6, 0x46, 7, 0x86, 8, 0x106, + }; + } +} diff --git a/Legacy/Pias/ArcDAT.cs b/Legacy/Pias/ArcDAT.cs new file mode 100644 index 00000000..e5c59263 --- /dev/null +++ b/Legacy/Pias/ArcDAT.cs @@ -0,0 +1,247 @@ +//! \file ArcDAT.cs +//! \date 2022 May 24 +//! \brief Pias resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Windows.Media; + +// [990528][Pias] Galfro ~Gal's Frontier~ + +namespace GameRes.Formats.Pias +{ + [Export(typeof(ArchiveFormat))] + public class DatOpener : ArchiveFormat + { + public override string Tag { get { return "DAT/PIAS"; } } + public override string Description { get { return "Pias resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + var arc_name = Path.GetFileName (file.Name).ToLowerInvariant(); + + string entry_type = null; + if ("voice.dat" == arc_name || "music.dat" == arc_name || "sound.dat" == arc_name) + entry_type = "audio"; + else if ("graph.dat" == arc_name) + entry_type = "image"; + else + return null; + + int resource_type = -1; + if ("graph.dat" == arc_name) + resource_type = 1; + else if ("sound.dat" == arc_name) + resource_type = 2; + + uint header_size = 1 == resource_type ? 8u : 4u; + List dir = null; + if (resource_type > 0) + { + var text_name = VFS.ChangeFileName (file.Name, "text.dat"); + if (!VFS.FileExists (text_name)) + return null; + using (var text_dat = VFS.OpenBinaryStream (text_name)) + { + var reader = new TextReader (text_dat); + dir = reader.GetResourceList (resource_type); + if (dir != null) + { + for (int i = dir.Count - 1; i >= 0; --i) + { + var entry = dir[i]; + entry.Size = file.View.ReadUInt32 (entry.Offset) + header_size; + entry.Name = i.ToString("D4"); + entry.Type = entry_type; + } + } + } + } + if (null == dir) + dir = new List(); + var known_offsets = new HashSet (dir.Select (e => e.Offset)); + long offset = 0; + while (offset < file.MaxOffset) + { + uint entry_size = file.View.ReadUInt32(offset) + header_size; + if (!known_offsets.Contains (offset)) + { + var entry = new Entry { + Name = dir.Count.ToString("D4"), + Type = entry_type, + Offset = offset, + Size = entry_size, + }; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + } + offset += entry_size; + } + return new ArcFile (file, this, dir); + } + + public override IImageDecoder OpenImage (ArcFile arc, Entry entry) + { + var input = arc.OpenBinaryEntry (entry); + return new GraphImageDecoder (input); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + if (entry.Type != "audio") + return base.OpenEntry (arc, entry); + uint size = arc.File.View.ReadUInt32 (entry.Offset); + var format = new WaveFormat + { + FormatTag = 1, + SamplesPerSecond = 22050, + BitsPerSample = 8, + }; + if (VFS.IsPathEqualsToFileName (arc.File.Name, "sound.dat")) + { + format.Channels = 2; + format.BlockAlign = 2; + } + else + { + format.Channels = 1; + format.BlockAlign = 1; + } + format.SetBPS(); + byte[] header; + using (var buffer = new MemoryStream()) + { + WaveAudio.WriteRiffHeader (buffer, format, size); + header = buffer.ToArray(); + } + var data = arc.File.CreateStream (entry.Offset+4, entry.Size-4); + return new PrefixStream (header, data); + } + } + + internal class TextReader + { + IBinaryStream m_input; + + public TextReader (IBinaryStream input) + { + m_input = input; + } + + public List GetResourceList (int resource_type) + { + List dir = null; + while (m_input.PeekByte() != -1) + { + byte op_code = m_input.ReadUInt8(); + if (op_code != 0x68) + { + Trace.WriteLine (string.Format ("unknown opcode 0x{0:X2} in text.dat", op_code), "DAT/PIAS"); + return null; + } + int type = ReadInt(); + int count = ReadInt(); + Action action = off => {}; + if (type == resource_type) + { + if (!ArchiveFormat.IsSaneCount (count)) + return null; + dir = new List (count); + action = off => dir.Add (new Entry { Offset = off }); + } + for (int i = 0; i < count; ++i) + { + uint offset = m_input.ReadUInt32(); + action (offset); + } + if (type == resource_type) + break; + } + return dir; + } + + private int ReadInt () + { + int result = m_input.ReadUInt8(); + int code = result & 0xC0; + if (0 == code) + return result; + result = (result & 0x3F) << 8 | m_input.ReadUInt8(); + if (0x40 == code) + return result; + result = result << 8 | m_input.ReadUInt8(); + if (0x80 == code) + return result; + return result << 8 | m_input.ReadUInt8(); + } + } + + internal class GraphImageDecoder : BinaryImageDecoder + { + public GraphImageDecoder (IBinaryStream input) : base (input, new ImageMetaData { BPP = 16 }) + { + m_input.ReadInt32(); // skip size + Info.Width = m_input.ReadUInt16(); + Info.Height = m_input.ReadUInt16(); + } + + protected override ImageData GetImageData () + { + m_input.Position = 8; + int plane_size = Info.iWidth * Info.iHeight; + var pixels = new byte[plane_size * 2]; + int dst = 0; + for (int p = 0; p < plane_size; ) + { + ushort word = m_input.ReadUInt16(); + if ((word & 0x8000) != 0) + { + int count = ((word >> 12) & 7) + 2; + p += count; + int offset = (word & 0xFFF) * 2; + count = Math.Min (count * 2, pixels.Length - dst); + Binary.CopyOverlapped (pixels, dst - offset, dst, count); + dst += count; + } + else + { + LittleEndian.Pack (word, pixels, dst); + dst += 2; + ++p; + } + } + int stride = Info.iWidth * 2; + return ImageData.Create (Info, PixelFormats.Bgr555, null, pixels, stride); + } + } +} diff --git a/Legacy/Properties/AssemblyInfo.cs b/Legacy/Properties/AssemblyInfo.cs index 91004130..a13ea4d9 100644 --- a/Legacy/Properties/AssemblyInfo.cs +++ b/Legacy/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.0.10.198")] -[assembly: AssemblyFileVersion ("1.0.10.198")] +[assembly: AssemblyVersion ("1.0.10.205")] +[assembly: AssemblyFileVersion ("1.0.10.205")] diff --git a/Legacy/SplushWave/ArcDAT.cs b/Legacy/SplushWave/ArcDAT.cs new file mode 100644 index 00000000..05b39396 --- /dev/null +++ b/Legacy/SplushWave/ArcDAT.cs @@ -0,0 +1,133 @@ +//! \file ArcDAT.cs +//! \date 2023 Aug 14 +//! \brief Splush Wave resource archive. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.SplushWave +{ + internal class FlkEntry : Entry + { + public byte Flags; + } + + [Export(typeof(ArchiveFormat))] + public class DatOpener : ArchiveFormat + { + public override string Tag { get { return "DAT/FLK"; } } + public override string Description { get { return "Splush Wave resource archive"; } } + public override uint Signature { get { return 0x4B4C46; } } // 'FLK' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + uint arc_size = file.View.ReadUInt32 (0x14); + if (arc_size != file.MaxOffset) + return null; + int count = file.View.ReadInt32 (0x18); + if (!IsSaneCount (count)) + return null; + + uint index_offset = 0x20; + var base_name = Path.GetFileNameWithoutExtension (file.Name); + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + var entry = new FlkEntry { + Name = string.Format ("{0}#{1:D4}", base_name, i), + Offset = file.View.ReadUInt32 (index_offset), + Size = file.View.ReadUInt32 (index_offset+4), + Flags = file.View.ReadByte (index_offset+0xF), + }; + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + index_offset += 0x10; + } + foreach (var entry in dir) + { + var type = file.View.ReadUInt32 (entry.Offset); + if (0x475753 == type || 0x475753 == (type >> 8)) + entry.Type = "image"; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var fent = (FlkEntry)entry; + var input = arc.File.CreateStream (entry.Offset, entry.Size); + if ((fent.Flags & 1) != 0) + { + using (input) + { + return LzssUnpack (input); + } + } + return input; + } + + internal Stream LzssUnpack (IBinaryStream input) + { + var frame = new byte[0x400]; + var output = new byte[0x200000]; + int dst = 0; + int frame_pos = 0x3BE; + int ctl = 0; + while (input.PeekByte() != -1) + { + ctl >>= 1; + if (0 == (ctl & 0x100)) + { + ctl = input.ReadByte() | 0xFF00; + } + if (0 == (ctl & 1)) + { + int next = input.ReadByte(); + if (-1 == next) + break; + output[dst++] = frame[frame_pos++ & 0x3FF] = (byte)next; + } + else + { + int lo = input.ReadByte(); + int hi = input.ReadByte(); + if (lo == -1 || hi == -1) + break; + int offset = lo + ((hi & 0xC0) << 2); + int count = (hi & 0x3F) + 3; + while (count --> 0) + { + output[dst++] = frame[frame_pos++ & 0x3FF] = frame[offset++ & 0x3FF]; + } + } + } + return new BinMemoryStream (output, 0, dst); + } + } +} diff --git a/Legacy/SplushWave/ImageSWG.cs b/Legacy/SplushWave/ImageSWG.cs new file mode 100644 index 00000000..41274bb9 --- /dev/null +++ b/Legacy/SplushWave/ImageSWG.cs @@ -0,0 +1,188 @@ +//! \file ImageSWG.cs +//! \date 2023 Aug 14 +//! \brief Splush Wave graphics format. +// +// Copyright (C) 2023 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.SplushWave +{ + internal class SwgMetaData : ImageMetaData + { + public uint PaletteOffset; + public uint DataOffset; + public byte Depth; + public bool IsCompressed; + } + + [Export(typeof(ImageFormat))] + public class SwgFormat : ImageFormat + { + public override string Tag { get { return "SWG"; } } + public override string Description { get { return "Splush Wave Graphics format"; } } + public override uint Signature { get { return 0x475753; } } // 'SWG' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x30); + uint pal_offset = header.ToUInt32 (0x14); + if (pal_offset != 0) + pal_offset += 0x10; + byte depth = header[0x28]; + return new SwgMetaData { + Width = header.ToUInt16 (0x20), + Height = header.ToUInt16 (0x22), + BPP = pal_offset != 0 ? 8 : depth == 2 ? 32 : 24, + DataOffset = header.ToUInt32 (0x10) + 0x10, + PaletteOffset = pal_offset, + Depth = depth, + IsCompressed = header[0x2F] != 0, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (SwgMetaData)info; + PixelFormat format = meta.BPP == 8 ? PixelFormats.Indexed8 + : meta.BPP == 32 ? PixelFormats.Bgr32 : PixelFormats.Bgr24; + BitmapPalette palette = null; + if (meta.BPP == 8) + { + file.Position = meta.PaletteOffset; + palette = ReadPalette (file.AsStream); + } + int stride = meta.iWidth * meta.BPP / 8; + file.Position = meta.DataOffset; +// var pixels = new byte[stride * meta.iHeight]; + var pixels = new byte[4 * meta.iWidth * meta.iHeight]; + if (!meta.IsCompressed) + { + file.Read (pixels, 0, pixels.Length); + return ImageData.CreateFlipped (meta, format, palette, pixels, stride); + } + var input = file.ReadBytes ((int)(file.Length - file.Position)); + if (!Decompress (input, pixels, meta.Depth + 2, meta.iWidth, meta.iHeight)) + throw new InvalidFormatException ("Invalid SWG file."); + return ImageData.CreateFlipped (meta, format, palette, pixels, stride); + } + + bool Decompress (byte[] input, byte[] output, int channels, int width, int height) + { + int src = 0; + if (input[0] != 0 || input[1] != 1) + { + int n = 0; + for (int i = 0; i < channels; ++i) + { + if (0 == input[i]) + ++n; + } + if (n != channels) + return false; + src = 4; + } + int compress_method = input[src+1] + (input[src] << 8); + src += 2; + if (0 == compress_method) + { + for (int i = 0; i < channels; ++i) + { + int pos = i; + int count = height * width; + while (count --> 0) + { + output[pos] = input[src++]; + pos += channels; + } + } + return true; + } + if (compress_method != 1) + return false; + int dst = 0; + int v33 = src; + int v37 = height * channels; + src += 2 * v37; + for (int row = 0; row < v37; ++row) + { + int y = row % height; + dst = channels * (width * (height - y - 1) + 1) - row / height - 1; + if (dst > output.Length) + return true; + int v24 = 0; + int v36 = input[v33+1] + (input[v33] << 8); + v33 += 2; + do + { + byte lo = input[src]; + byte hi = input[src+1]; + if (lo != 0) + { + if (lo < 0x81) + { + ++src; + int count = lo + 1; + v24 += count + 1; + while (count --> 0) + { + output[dst] = input[src++]; + dst += channels; + } + } + else + { + src += 2; + v24 += 2; + int count = Math.Min (0x101 - lo, output.Length - dst); + while (count --> 0) + { + output[dst] = hi; + dst += channels; + } + } + } + else + { + src += 2; + v24 += 2; + output[dst] = hi; + dst += channels; + } + if (dst >= output.Length) + return true; + } + while (v24 < v36); + } + return true; + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("SwgFormat.Write not implemented"); + } + } +} diff --git a/Legacy/StudioFoma/ArcARC.cs b/Legacy/StudioFoma/ArcARC.cs new file mode 100644 index 00000000..f0e02fd5 --- /dev/null +++ b/Legacy/StudioFoma/ArcARC.cs @@ -0,0 +1,125 @@ +//! \file ArcARC.cs +//! \date 2022 Jun 25 +//! \brief I's9 / Studio FOMA resource archive. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Linq; + +// [991119][I’s9] Lovemation + +namespace GameRes.Formats.Foma +{ + [Serializable] + public class Is9Scheme : ResourceScheme + { + public IDictionary> KnownSchemes; + } + + [Export(typeof(ArchiveFormat))] + public class ArcOpener : ArchiveFormat + { + public override string Tag { get { return "ARC/FOMA"; } } + public override string Description { get { return "I's9/Studio FOMA resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public override ArcFile TryOpen (ArcView file) + { + var arc_name = Path.GetFileName (file.Name).ToUpperInvariant(); + if (!KnownArcNames.Contains (arc_name)) + return null; + var dir_name = VFS.GetDirectoryName (file.Name); + foreach (var scheme in KnownSchemes) + { + var exe_name = VFS.CombinePath (dir_name, scheme.Key); + if (VFS.FileExists (exe_name)) + { + uint table_offset; + if (scheme.Value.TryGetValue (arc_name, out table_offset)) + { + var dir = GetEntryList (exe_name, table_offset, file.MaxOffset); + if (dir != null) + return new ArcFile (file, this, dir); + } + } + } + return null; + } + + internal List GetEntryList (string exe_name, long table_offset, long max_offset) + { + using (var exe_file = VFS.OpenView (exe_name)) + { + if (table_offset >= exe_file.MaxOffset) + return null; + var exe = new ExeFile (exe_file); + var dir = new List(); + while (table_offset+12 <= exe_file.MaxOffset) + { + uint name_addr = exe.View.ReadUInt32 (table_offset); + if (0 == name_addr) + break; + var name = exe.GetCString (name_addr); + if (string.IsNullOrEmpty (name)) + return null; + var entry = Create (name); + entry.Offset = exe.View.ReadUInt32 (table_offset + 4); + entry.Size = exe.View.ReadUInt32 (table_offset + 8); + if (!entry.CheckPlacement (max_offset)) + return null; + dir.Add (entry); + table_offset += 12; + } + return dir; + } + } + + Is9Scheme m_scheme = new Is9Scheme + { + KnownSchemes = new Dictionary>() + }; + + HashSet m_known_arc_names = null; + + public override ResourceScheme Scheme + { + get { return m_scheme; } + set { m_scheme = (Is9Scheme)value; m_known_arc_names = null; } + } + + internal IDictionary> KnownSchemes + { + get { return m_scheme.KnownSchemes; } + } + + internal HashSet KnownArcNames + { + get { return m_known_arc_names ?? (m_known_arc_names = new HashSet (KnownSchemes.Values.SelectMany (v => v.Keys))); } + } + } +} diff --git a/Legacy/Uran/ArcNCL.cs b/Legacy/Uran/ArcNCL.cs index e792238e..c7515e9a 100644 --- a/Legacy/Uran/ArcNCL.cs +++ b/Legacy/Uran/ArcNCL.cs @@ -23,13 +23,15 @@ // IN THE SOFTWARE. // -using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; using GameRes.Compression; +using ICSharpCode.SharpZipLib.BZip2; // [000224][Uran] P.S. 3 ~Harem Night~ +// [980828][Uran] College Terra Story +// [971218][Uran] GirlDollToy namespace GameRes.Formats.Uran { @@ -38,9 +40,7 @@ namespace GameRes.Formats.Uran public byte Method; } -#if DEBUG [Export(typeof(ArchiveFormat))] -#endif public class NclOpener : ArchiveFormat { public override string Tag { get { return "NCL"; } } @@ -96,9 +96,7 @@ namespace GameRes.Formats.Uran if (2 == nclent.Method) input = new ZLibStream (input, CompressionMode.Decompress); else if (3 == nclent.Method) - { - // XXX bzip2 compression not implemented - } + input = new BZip2InputStream (input); } return input; } @@ -130,7 +128,7 @@ namespace GameRes.Formats.Uran int b = BaseStream.ReadByte(); if (-1 != b) { - b -= m_key; + b = (byte)(b - m_key); } return b; } diff --git a/Legacy/Uran/ImageDAR.cs b/Legacy/Uran/ImageDAR.cs new file mode 100644 index 00000000..1a55b80c --- /dev/null +++ b/Legacy/Uran/ImageDAR.cs @@ -0,0 +1,145 @@ +//! \file ImageDAR.cs +//! \date 2022 May 11 +//! \brief Uran image format. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +// [970525][Uran] High School Terra Story + +namespace GameRes.Formats.Uran +{ + public class DarMetaData : ImageMetaData + { + public byte Version; + public int FrameCount; + public long FrameOffset; + public int RowSize; + } + + [Export(typeof(ImageFormat))] + public class DarFormat : ImageFormat + { + public override string Tag { get { return "DAR"; } } + public override string Description { get { return "Uran image format"; } } + public override uint Signature { get { return 0x3A524144; } } // 'DAR:' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (12); + byte version = header[5]; + int frame_count = header.ToUInt16 (6); + if (header[4] != '8' || version > 1 || frame_count < 1) + return null; + file.Position = 0x40C; + int header_size = 8; + if (version != 0) + header_size = file.ReadUInt16(); + long frame_offset = file.Position; + ushort width = file.ReadUInt16(); // +0 + ushort height = file.ReadUInt16(); // +1 + ushort row_size = file.ReadUInt16(); // +2 + file.ReadUInt16(); // +3 + int bpp = 8; + if (header_size >= 14) + { + file.ReadInt16(); // +4 + file.ReadInt16(); // +5 + file.ReadUInt16(); // +6 height + if (header_size >= 16) + { + int count = file.ReadUInt8(); // [14] + if (count + 18 <= header_size) + { + file.Seek (count - 1, SeekOrigin.Current); + bpp = file.ReadUInt8(); // [count+14] + } + } + } + return new DarMetaData { + Width = width, + Height = height, + BPP = bpp, + Version = version, + FrameCount = frame_count, + FrameOffset = frame_offset + header_size, + RowSize = row_size, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var reader = new DarReader (file, (DarMetaData)info); + return reader.Unpack(); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("DarFormat.Write not implemented"); + } + } + + internal class DarReader + { + IBinaryStream m_input; + DarMetaData m_info; + + public ImageMetaData Info { get { return m_info; } } + public BitmapPalette Palette { get; private set; } + + public DarReader (IBinaryStream input, DarMetaData info) + { + m_input = input; + m_info = info; + } + + public ImageData Unpack () + { + if (8 == m_info.BPP) + { + m_input.Position = 0x0C; + Palette = ImageFormat.ReadPalette (m_input.AsStream); + } + int depth = m_info.BPP / 8; + long row_pos = m_info.FrameOffset; + int stride = m_info.iWidth * depth; + var pixels = new byte[stride * m_info.iHeight]; + int dst = pixels.Length - stride; + while (dst >= 0) + { + m_input.Position = row_pos; + int x = m_input.ReadInt16(); + int row_length = m_input.ReadUInt16(); + if (row_length != 0) + m_input.Read (pixels, dst + x, row_length); + row_pos += m_info.RowSize; + dst -= stride; + } + PixelFormat format = depth == 1 ? PixelFormats.Indexed8 : PixelFormats.Bgr24; + return ImageData.Create (m_info, format, Palette, pixels, stride); + } + } +} diff --git a/Legacy/Uran/ImageNCL.cs b/Legacy/Uran/ImageNCL.cs new file mode 100644 index 00000000..9dde071e --- /dev/null +++ b/Legacy/Uran/ImageNCL.cs @@ -0,0 +1,101 @@ +//! \file ImageNCL.cs +//! \date 2022 May 11 +//! \brief Uran multi-frame image. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using GameRes.Compression; +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace GameRes.Formats.Uran +{ + public class NclMetaData : ImageMetaData + { + public int DataOffset; + } + + [Export(typeof(ImageFormat))] + public class NclFormat : ImageFormat + { + public override string Tag { get { return "NCL/URAN"; } } + public override string Description { get { return "Uran multi-frame image format"; } } + public override uint Signature { get { return 0; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + if (!file.Name.HasExtension (".ncl")) + return null; + var header = file.ReadHeader (0x10); + int size = header.ToInt32 (0); + int name_length = header.ToUInt16 (8); + if (size <= 1 || 0 == name_length || name_length > 0x100) + return null; + int pos = 10 + name_length + 6; + header = file.ReadHeader (pos + 9); + var name = header.GetCString (10, name_length); + if (!name.HasExtension (".bmp")) + return null; + int header_size = header.ToUInt16 (pos-2); + if (header_size < 9 || header_size > 0x40 || pos + header_size + size > file.Length) + return null; + uint width = header.ToUInt32 (pos+1); + uint height = header.ToUInt32 (pos+5); + return new NclMetaData { + Width = width, + Height = height, + BPP = 8, + DataOffset = pos + header_size, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (NclMetaData)info; + file.Position = meta.DataOffset; + Stream input = new NclSubStream (file.AsStream, 10, true); + try + { + int method = input.ReadByte(); + if (2 == method) + input = new ZLibStream (input, CompressionMode.Decompress); + + var decoder = new BmpBitmapDecoder (input, + BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + var frame = decoder.Frames[0]; + frame.Freeze(); + return new ImageData (frame, info); + } + finally + { + input.Dispose(); + } + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("NclFormat.Write not implemented"); + } + } +} diff --git a/Legacy/Yaneurao/ArcDAT.cs b/Legacy/Yaneurao/ArcDAT.cs index 64de3157..f3b44359 100644 --- a/Legacy/Yaneurao/ArcDAT.cs +++ b/Legacy/Yaneurao/ArcDAT.cs @@ -31,6 +31,8 @@ using GameRes.Compression; // [030704][Error] Kakoi ~Zetsubou no Shojo Kangokujima~ // [040227][Deko Pon!] Itsuka Furu Yuki +// [051216][Studio Ebisu] Nyuu wa SHOCK!! ~Pai o Torimodose!~ +// [100126][Yaoyorozu-Kobo] Toraware no Seikishi Riisha namespace GameRes.Formats.Yaneurao { diff --git a/Legacy/hmp/ImageCBF.cs b/Legacy/hmp/ImageCBF.cs new file mode 100644 index 00000000..595791c4 --- /dev/null +++ b/Legacy/hmp/ImageCBF.cs @@ -0,0 +1,72 @@ +//! \file ImageCBF.cs +//! \date 2022 May 19 +//! \brief h.m.p image format. +// +// Copyright (C) 2022 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; + +// [990521][Sepia] Hikari no Naka de Dakishimete + +namespace GameRes.Formats.Hmp +{ + [Export(typeof(ImageFormat))] + public class CbfFormat : ImageFormat + { + public override string Tag { get { return "CBF/MA"; } } + public override string Description { get { return "h.m.p image format"; } } + public override uint Signature { get { return 0x432D414D; } } // 'MA-CBF' + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x1C); + if (!header.AsciiEqual ("MA-CBF")) + return null; + return new ImageMetaData { + Width = header.ToUInt32 (0x10), + Height = header.ToUInt32 (0x14), + BPP = 16, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + file.Position = 0x24; + int stride = info.iWidth * 2; + var pixels = new byte[stride * info.iHeight]; + file.Read (pixels, 0, pixels.Length); + return ImageData.CreateFlipped (info, PixelFormats.Bgr555, null, pixels, stride); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("CbfFormat.Write not implemented"); + } + } + + [Export(typeof(ResourceAlias))] + [ExportMetadata("Extension", "NE")] + [ExportMetadata("Target", "WAV")] + public class NeFormat : ResourceAlias { } +} diff --git a/Legacy/packages.config b/Legacy/packages.config new file mode 100644 index 00000000..2d9fe72d --- /dev/null +++ b/Legacy/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/supported.html b/docs/supported.html index af054f45..1e3b081f 100644 --- a/docs/supported.html +++ b/docs/supported.html @@ -8,8 +8,8 @@ body { font-family: Calibri, sans-serif } table { border-spacing: 0; border-collapse: collapse; } th,td { vertical-align: text-top; border: solid black 1px; } tr.odd td { background-color: #eee } -tr { height: 100% } -tr.last { height: auto } +tr { height: auto } +tr.last { height: 100% } .footnote { font-size: 75%; vertical-align: super; top: 0.5em } .footnote::before { content: "[" } .footnote::after { content: "]" } @@ -584,6 +584,7 @@ Douryou no Oku-san ~Netori Tsuma, Netorare Tsuma~ ShiinaR Draculius ShiinaRio v2.38
Engage Links ShiinaRio v2.45
Enkaku Sousa 2.36 or 2.37
+Gakuen Pets ~Houkago no Shiikusha~ 2.40
Gakushoku no Oba-san The Motion ShiinaRio v2.48
Gensou no Idea ~Oratorio Phantasm Historia~ShiinaRio v2.49
Gibo to Oba ~Soshite Yuujin no Haha~ ShiinaRio v2.36
@@ -1303,9 +1304,10 @@ Eien no Aselia -The Spirit of Eternity Sword- Ayakashi
Ayakashi H
-*.arcLIN2
LINK3
LINK5
LINK6
UF01KaGuYa +*.arcLIN2
LINK3
LINK5
LINK6
UF01KaGuYa Dokidoki Onee-san
Harami Tama
+Kirari☆Nangoku Komugiiro
Mahokoi ~Ecchi na Mahou de Koi x Koi Shichau~
Mainichi ga M!
Meidokissa
@@ -1317,7 +1319,8 @@ Toshishita Gentei Nuki x2 Share-house
*.alpAP-0
AP-2 *.ap3\x04APS3 -*.anmAN00
AN21 +*.anmAN00
AN10
AN20
AN21 +*.pltPL00 *.pcsPCCSC's ware Gakuen Ojou-sama Kitan
Kuro to Kuro to Kuro no Saidan ~Kodoku~
@@ -1484,6 +1487,7 @@ Eijin-sou
Etsuraku no Tane
Fit Shichao! ~Toshiue Josei to Asedaku Lesson Hatsutaiken~
Fuka no Jugoku
+Gacha-kami-sama no Iu Toori!
Gakkou Yarashii Kaidan
Gibo no Shizuku ~Shimetta Hada kara Kaori Tatsu Amai Iroka~
Gibo no Toiki ~Haitoku Kokoro ni tadayou Haha no Iroka~
@@ -1503,6 +1507,7 @@ Hidamari no Kage de
Hime Kami 1/2
Hitohada Nugimasu! Shinmai Henshuu Marika no Junan
Hitozuma Kasumi-san 2
+Hoiku Shichao!
Iji Care ~Noel-kun no Gohoushi Nikki~
Ikareta Kyoushitsu
Inhou no Seijo ~The Nuns of Sexualministrant~
@@ -1521,6 +1526,7 @@ Koitsuma Biyori ~Yukino-san wa Hitozuma Kanrinin~
Kowaku no Toki
Kuraibito
Mahou Shoujo Nayuta
+Maniac Circle Hakusho.rar
Mouryou no Nie
Mugen no Sakura ~Hitsuya-hime Injoku Youshokutan~
Natsu Doki! Harem
@@ -1543,6 +1549,7 @@ Shukubo no Uzuki ~Hitozuma Miboujin no Nareta Karada to Amai Toiki~
Shukubo no Uzuki 2 ~Nareta Hitozuma kara Tadayou "Onna" no Iroka~
Shukujo no Tsuyagoto
Volley Coaching!
+Youka no Sono
Yumekoi Tensei
Zettai Maji Love! Amaicha Happening!
Zettai Majiiki!? Ichazura Happening!
@@ -1582,13 +1589,14 @@ Shokusou Tenshi Serika 2
Elevator Panic ~Misshitsu no Inkou~
Yuuguu Settai #
-*.datMIK01
MK2.0
BL2.0
SL1.0MAIKA +*.datMIK01
MK2.0
BL2.0
SL1.0
MP2.0MAIKA Choukou Sentai Justice Blade 2
Inka Gakuen Taisen
Ippai, Oshiete! ~Imouto Communication♪~
Princess Moon ~Seihouseki Kishidan no Juunan~
Ryoujoku Hishoshitsu
Ryoujoku Onna Kyoushi ~Reijin Tenraku Hen~
+Suisui -Sweetheart Swimmer-
Uchuu Keiji Soldivan
*.wavWV5A @@ -1775,6 +1783,7 @@ Mite Kudasaimasu?
*.vmd- *.dpm
*.binDPMXHot Soup Processor femme fatale
+Mawasarehime -Hakudaku no Kioku-
*.cdt
*.pdt
*.vdt
*.ovdRK1NEJII Kidou Houshinki
@@ -2044,6 +2053,16 @@ Kazoku Keikaku Re:Tsumugu Ito
*.datCsPack2CatSystem Yuibashi
+*.pck-Strikes +Niizuma Kyoushi Kagurazaka Naomi
+Shachou Hisho Nozaki Reika
+ +*.lag\x01\x10LA +*.pac-ads +Injoku Hitozuma Onna Kyoushi
+Inran Hitozuma Apart
+ +*.060POG

1 Non-encrypted only