From 42d4c33a0b6093f09149ddaf784d07e0c1e82e07 Mon Sep 17 00:00:00 2001 From: akiWagashi Date: Sun, 1 Mar 2026 13:51:44 +0800 Subject: [PATCH] Add support for new Circus Voice.dat format Delete unused namespace --- ArcFormats/Circus/ArcCircus.cs | 69 +++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/ArcFormats/Circus/ArcCircus.cs b/ArcFormats/Circus/ArcCircus.cs index 5a2d2958a..065dde314 100644 --- a/ArcFormats/Circus/ArcCircus.cs +++ b/ArcFormats/Circus/ArcCircus.cs @@ -47,20 +47,46 @@ public DatOpener () public override ArcFile TryOpen (ArcView file) { - int count = file.View.ReadInt32 (0); + var arcFile = TryOpenFromHeader(file); + if (null != arcFile) + { + return arcFile; + } + + arcFile = TryOpenFromFooter(file); + + return arcFile; + } + + public ArcFile TryOpenFromHeader(ArcView file) + { + int count = file.View.ReadInt32(0); if (count <= 1 || count > 0xfffff) return null; - var dir = ReadIndex (file, count, 0x24); + var dir = ReadIndexV1(file, count, 0x24); if (null == dir) - dir = ReadIndex (file, count, 0x30); + dir = ReadIndexV1(file, count, 0x30); if (null == dir) - dir = ReadIndex (file, count, 0x3C); + dir = ReadIndexV1(file, count, 0x3C); if (null == dir) return null; - return new ArcFile (file, this, dir); + return new ArcFile(file, this, dir); + } + + public ArcFile TryOpenFromFooter(ArcView file) + { + int count = file.View.ReadInt32(file.MaxOffset - 4); + if(count <= 1 || count > 0xfffff) + { + return null; + } + + var dir = ReadIndexV2(file, count, file.View.ReadInt32(file.MaxOffset - 0x8)); + + return new ArcFile(file, this, dir); } - private List ReadIndex (ArcView file, int count, int name_length) + private List ReadIndexV1 (ArcView file, int count, int name_length) { long index_offset = 4; uint index_size = (uint)((name_length + 4) * count); @@ -98,5 +124,36 @@ private List ReadIndex (ArcView file, int count, int name_length) } return dir; } + + private List ReadIndexV2(ArcView file, int count, long start_offset) + { + uint max_index_size = (uint)(count * 0x4C); + long index_offset = start_offset; + var dir = new List (count); + + file.View.Reserve(start_offset, max_index_size); + + for (int i = 0; i < count; i++) + { + int name_length = file.View.ReadByte(index_offset); + index_offset++; + + string name = file.View.ReadString(index_offset, (uint)name_length); + index_offset += name_length; + + uint entry_size = file.View.ReadUInt32(index_offset); + index_offset += 8; + + long entry_offset = file.View.ReadInt32(index_offset); + index_offset += 4; + + var entry = FormatCatalog.Instance.Create(name); + entry.Size = entry_size; + entry.Offset = entry_offset; + dir.Add(entry); + } + + return dir; + } } }