diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 0b37488c..97e1b49a 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -607,6 +607,7 @@ + diff --git a/ArcFormats/Musica/ArcMIP.cs b/ArcFormats/Musica/ArcMIP.cs new file mode 100644 index 00000000..18c54597 --- /dev/null +++ b/ArcFormats/Musica/ArcMIP.cs @@ -0,0 +1,655 @@ +//! \file ArcMIP.cs +//! \date 2026-01-16 +//! \brief Minori resource archive. +// +// Copyright (C) 2026 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.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using GameRes.Utility; + +namespace GameRes.Formats.Musica { + [Export(typeof(ArchiveFormat))] + public class MipOpener : ArchiveFormat { + public override string Tag { get { return "MIP"; } } + public override string Description { get { return "Minori resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + // 0x42e100 + static readonly uint[] resEntrySizeList = { + 0xDDE, + 0x1622, + 0x44F, + 0xF06, + 0x1EFEA, + 0x64B3, + 0x10684E, + 0x9288, + 0x144, + 0x49993, + 0x5065C, + 0x52424, + 0x4EB4B, + 0x4EA1F, + 0x4A334, + 0x4B8E4, + 0x55DA6, + 0x56D7C, + 0x3A3ED, + 0x307B3, + 0x55FB8, + 0x96D68, + 0x4B821, + 0x4C33B, + 0x54EB3, + 0x4DBDD, + 0x52D69, + 0x50A3F, + 0x50C0C, + 0x4975A, + 0x47E5F, + 0x37177, + 0x3E0D4, + 0x46029, + 0xC854A, + 0x4463F, + 0x44E40, + 0x40AA5, + 0x432BF, + 0x3C0A5, + 0x29496, + 0xABC1B, + 0x88427, + 0x9F549, + 0x104EA, + 0x7C524, + 0x75CE, + 0xA419, + 0x6419, + 0x9C62, + 0x6A9C, + 0xC5862, + 0x134F2D, + 0x1271, + 0x11D6, + 0x4D1F, + 0x6134, + 0x63C1, + 0x8730, + 0x6BF9, + 0x6CDA, + 0x898A, + 0x706B, + 0x696A, + 0x60AA, + 0x9007, + 0x662F, + 0x72B3, + 0x55E8, + 0x6E47, + 0x9EDA, + 0x622D, + 0x5BE4, + 0x73A9, + 0x9269, + 0x5C11, + 0x553A, + 0x66EA, + 0x7174, + 0x6A8C, + 0x6AC0, + 0x6389, + 0x7167, + 0x845A, + 0x900A, + 0x726E, + 0x68F3, + 0x88E4, + 0x8B70, + 0x83BB, + 0x7D1E, + 0x84CC, + 0x583C, + 0x6AD1, + 0x7981, + 0x48F0, + 0x765A, + 0x763F, + 0x5ACB, + 0x5B4E, + 0x6490, + 0x7441, + 0x5D9F, + 0x5FD9, + 0x5E9A, + 0x7330, + 0x69D1, + 0x86BE, + 0x92AC, + 0x9787, + 0x972D, + 0x9963, + 0x96E3, + 0x8101, + 0x707C, + 0x70DC, + 0x9105, + 0x7A06, + 0x7A8F, + 0x595F, + 0x58FA, + 0x7F95, + 0x86CB, + 0x86F7, + 0x7B3B, + 0x8971, + 0x8BFC, + 0x7FE6, + 0x77EE, + 0x83FF, + 0x606D, + 0x6125, + 0x66FB, + 0x66F9, + 0x6E76, + 0x6826, + 0x67B1, + 0x76E3, + 0x7487, + 0x4E7B, + 0x4CD34, + 0x750EF, + 0x761B6, + 0xB29F9, + 0x9CE38, + 0x95BEF, + 0x79F4F, + 0x9BEB6, + 0xA1C95, + 0x72147, + 0x68007, + 0x59070, + 0xCADF5, + 0x71FB4, + 0x67BF2, + 0x5C639, + 0x57FAF, + 0x63334, + 0x703D2, + 0x5DCDB, + 0xA796B, + 0x71728, + 0x7F52D, + 0x71B7A, + 0xA024D, + 0x73670, + 0x47E4B, + 0x63AF1, + 0x83F4F, + 0x6FFB2, + 0x82C74, + 0x708D6, + 0x79208, + 0x99011, + 0x8CFD4, + 0x7B119, + 0x65D69, + 0x982BA, + 0x86387, + 0x7F047, + 0x91A4A, + 0x9B149, + 0x65C0F, + 0x8050B, + 0x75798, + 0x369A9, + 0x39FD1, + 0x6E791, + 0x6E31B, + 0x558B7, + 0x66149, + 0x5C5FE, + 0x6A9CC, + 0x670E8, + 0x687DA, + 0x5F998, + 0x69569, + 0x5EF73, + 0x789BD, + 0xAE0EC, + 0xB7733, + 0x9422C, + 0xB1BBE, + 0xAC68D, + 0x91074, + 0x65FC9, + 0x6664C, + 0xB0867, + 0x6992C, + 0x6A4A9, + 0x5011C, + 0x5ECBB, + 0xA4332, + 0x7411F, + 0x73E87, + 0x7322C, + 0x82260, + 0x8E294, + 0x82594, + 0x6F54E, + 0x80E86, + 0x535AF, + 0x545B0, + 0x50437, + 0x503C8, + 0x56674, + 0x4E048, + 0x4D5C8, + 0x654DD, + 0x67968, + 0x5AAAA, + 0x2F45, + 0x3098, + 0x3DF5F, + 0xE6D49, + 0xD866D, + 0x9632C, + 0xE20BD, + 0x33061, + 0x375DF, + 0x417C2, + 0x37764, + 0x37934, + 0x40807, + 0xCDA33, + 0x9FA9C, + 0x44103, + 0xDA3E9, + 0x44E92, + 0x3C9DB, + 0x46F57, + 0x3881A, + 0x3A9B9, + 0x3B0A8, + 0x430A8, + 0xE2156, + 0x415F1, + 0x318EC, + 0x3AFCC, + 0x39769, + 0xDCEA7, + 0x4E43C, + 0x3CC83, + 0xBDF5E, + 0x33CF8, + 0x6D250, + 0x8570A, + 0x60C21, + 0x9782C, + 0x783D0, + 0x783D0, + 0x67935, + 0xAA5A7, + 0xDCA2E, + 0x606E9, + 0xA9047, + 0x10E5F, + 0x10E92, + 0x10E61, + 0x136E5, + 0x136EB, + 0x1371A, + 0x1368E, + 0x13818, + 0x139D4, + 0x11350, + 0x11372, + 0x11372, + 0x115CD, + 0x161F1, + 0x16022, + 0x16176, + 0x1503F, + 0x140CC, + 0x144D3, + 0x1433F, + 0x1365E, + 0x1388C, + 0x1365C, + 0x138FE, + 0x13616, + 0x1389D, + 0x13312, + 0x134A5, + 0x18BC8, + 0x18CD9, + 0x1785D, + 0x17A8A, + 0x176B5, + 0x17924, + 0x177F4, + 0x17A2D, + 0x1786E, + 0x17A9D, + 0x101CA, + 0x101AE, + 0x1058B, + 0x10184, + 0xD8D3, + 0xD936, + 0xD8AB, + 0xDA4E, + 0x11968, + 0x11935, + 0x11988, + 0x119D4, + 0x11938, + 0x1282A, + 0x127E9, + 0x12836, + 0x12813, + 0x12803, + 0xFC09, + 0xFBF2, + 0xEFE0, + 0xF149, + 0xEECF, + 0xEFF5, + 0xF02E, + 0xE872, + 0xEA4C, + 0xE871, + 0xE778, + 0xF835, + 0xFB43, + 0xF91B, + 0xFC05, + 0xE75F, + 0xE7DC, + 0x10295, + 0x102A9, + 0x102B6, + 0xD72E, + 0xD713, + 0xF21D, + 0xF51B, + 0xF26C, + 0xF55D, + 0x117B0, + 0x117B7, + 0x11783, + 0x1171E, + 0x118CD, + 0x118F0, + 0x119ED, + 0x18318, + 0x18300, + 0x182EF, + 0x18710, + 0x13F5F, + 0x13E96, + 0x13E4D, + 0x13FA9, + 0x13B17, + 0x13A41, + 0x13962, + 0x13C14, + 0x1396E, + 0x13569, + 0x13830, + 0xF939, + 0xF901, + 0xF925, + 0xEB9A, + 0x10C46, + 0x10B7D, + 0xEB8E, + 0x10B3A, + 0xEB68, + 0x10B1C, + 0xEB5F, + 0x10B5A, + 0xEC53, + 0xE494, + 0xE4B0, + 0x11A7C, + 0x1152B, + 0x11ABA, + 0x11620, + 0x11A1A, + 0x114E0, + 0x144EE, + 0x149CF, + 0x14519, + 0x10B71, + 0x10AFA, + 0x10B04, + 0xF64E, + 0xF8B2, + 0xF65F, + 0xF90E, + 0xF5C0, + 0xF87D, + 0xF5CC, + 0xF89A, + 0xF5A2, + 0xF883, + 0xF4CE, + 0xF7C6, + 0xF6E2, + 0xF326, + 0xF31D, + 0xFE72, + 0xFE64, + 0xFE4B, + 0x101B2, + 0xF1FF, + 0x10D8C, + 0x101F6, + 0xF2DD, + 0x10244, + 0xF1B6, + 0x101D9, + 0xFDC3, + 0x10363, + 0xFEB9, + 0x13450, + 0x133C1, + 0x126D1, + 0x115B8, + 0x126AD, + 0x115BC, + 0x26EA8, + 0x26E49, + 0x10A6F, + 0x10AE4, + 0x10A3F, + 0xFEC0, + 0xFF2F, + 0xFE55, + 0x13D6A, + 0x13DB7, + 0x13D94, + 0x13C03, + 0x123AD, + 0x121E2, + 0x12342, + 0x1252A, + 0x126A0, + 0x1285E, + 0xDD8C, + 0xDB7C, + 0xDAA5, + 0xD2A8, + 0xD564, + 0xD2F6, + 0xD6D1, + 0xD3F3, + 0xD775, + 0xD2F5, + 0xD8AE, + 0xD824, + 0xD8A2, + 0x1532E, + 0x151B5, + 0x12F49, + 0x141C8, + 0x12EA7, + 0x12E57, + 0x12F0B, + 0x12EF5, + 0x13131, + 0x15066, + 0x15003, + 0x150CD, + 0x10C4B, + 0x112CE, + 0x112AD, + 0x10C21, + 0x112B3, + 0x10CDF, + 0x113AF, + 0x10CA1, + 0x1133C, + 0x10C4B, + 0x11915, + 0x11900, + 0x118CA, + 0x118AC, + 0x11985, + 0x107CC, + 0x10759, + 0x1071B, + 0x4D14, + 0x4EF7, + 0x5804, + 0x5BDA, + 0x3BB7, + 0x30BD, + 0x39E0, + 0x3A3C, + 0x3AF2, + 0x3A3C, + 0x3969, + 0x393C, + 0x3B8C, + 0x4040, + 0x37FC, + 0x3973, + 0x3856, + 0x397B, + 0x3865, + 0x38DD, + 0x44C5, + 0x37C0, + 0x3BD9, + 0x3887, + 0x3C29, + 0x3BFA, + 0x3199, + 0x4848, + 0x151FD, + 0xD890, + 0x24E0A, + 0xBFAD, + 0x1531A, + 0x1B25F + }; + + // 0x42f1d0 + static readonly uint[] scEntrySizeList = { + 0x1D1E7, + 0x130B4, + 0xE7AB, + 0xEC2E, + 0x1408A, + 0x96C8, + 0x1006F, + 0x109D8, + 0x1389F, + 0xEA2E, + 0xE57C, + 0xD331, + 0xD0F1, + 0x11730, + 0x12FC4, + 0xCC50, + 0xE043, + 0xD7AB, + 0x18978, + 0x2F87, + 0x4, + 0x22F3, + 0x6C2A, + 0x28BE, + 0x4080, + 0x3897 + }; + + public MipOpener() { + Extensions = new string[] { "mip" }; + } + + public override ArcFile TryOpen(ArcView file) { + string extension; + uint[] sizes; + + string basename = Path.GetFileName(file.Name).ToLower(); + if (basename == "res.mip") { + extension = ".png"; + sizes = resEntrySizeList; + } + else if (basename == "sc.mip") { + extension = ""; + sizes = scEntrySizeList; + } + else + return null; + + int count = sizes.Length; + var dir = new List(count); + uint offset = 0; + for (int i = 0; i < count; i++) { + var entry = new Entry { + Name = i.ToString("D4") + extension, + Type = extension == "" ? "script" : "image", + Offset = offset, + Size = sizes[i] + }; + dir.Add(entry); + offset += entry.Size; + } + + return new ArcFile(file, this, dir); + } + + public override Stream OpenEntry(ArcFile arc, Entry entry) { + var s = new XoredStream(arc.File.CreateStream(entry.Offset, entry.Size), 0xFF); + if (entry.Name.EndsWith(".png")) + return new PrefixStream(PngFormat.HeaderBytes, s); + return s; + } + } +}