From 797816f856313ca15cf21065b7e546a039cffd9b Mon Sep 17 00:00:00 2001 From: ManicSteiner Date: Tue, 5 Dec 2023 00:41:53 +0800 Subject: [PATCH] feat: support Rune Princess archive --- ArcFormats/ArcFormats.csproj | 1 + ArcFormats/MAGES/ArcARC20.cs | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 ArcFormats/MAGES/ArcARC20.cs diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 917a6f11..515f6642 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -169,6 +169,7 @@ + diff --git a/ArcFormats/MAGES/ArcARC20.cs b/ArcFormats/MAGES/ArcARC20.cs new file mode 100644 index 00000000..a0869ab7 --- /dev/null +++ b/ArcFormats/MAGES/ArcARC20.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Text; + +namespace GameRes.Formats.MAGES +{ + [Export(typeof(ArchiveFormat))] + public class ARC20Opener : ArchiveFormat + { + public override string Tag { get { return "ARC/Princess Soft ARC20"; } } + public override string Description { get { return "Princess Soft PS2 resource archive"; } } + public override uint Signature { get { return 0x20435241; } } // 'ARC\x20' + 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 filename_end = file.View.ReadUInt32(8); + var dir = new List(count); + uint index_offset; + for (int i = 0; i < count; ++i) + { + index_offset = file.View.ReadUInt32(16 * i + 16); + byte c; + List namebyte = new List(); + while (true) + { + c = file.View.ReadByte((long)index_offset); + if (c == 0 | index_offset > filename_end) break; + namebyte.Add(c); + index_offset++; + } + var sjis = System.Text.Encoding.GetEncoding("Shift-JIS"); + var name = sjis.GetString(namebyte.ToArray()); + var entry = Create(name); + + entry.Offset = file.View.ReadUInt32(16 * i + 16 + 4) * 2048; + + entry.Size = file.View.ReadUInt32(16 * i + 16 + 8); + entry.UnpackedSize = file.View.ReadUInt32(16 * i + 16 + 8); + if (!entry.CheckPlacement(file.MaxOffset)) + return null; + dir.Add(entry); + } + return new ArcFile(file, this, dir); + } + } +}