mirror of
https://github.com/crskycode/GARbro.git
synced 2026-06-06 05:38:48 +08:00
feat: support new index format of Cyberworks/TinkerBell games after 2024
This commit is contained in:
@@ -220,7 +220,7 @@ namespace GameRes.Formats.Cyberworks
|
||||
var toc = ReadToc (toc_name, 8);
|
||||
if (null == toc)
|
||||
return null;
|
||||
using (var index = new ArcIndexReader (toc, file, arc_idx, game_name))
|
||||
using (var index = GetIndexReader (toc, file, arc_idx, game_name))
|
||||
{
|
||||
if (!index.Read())
|
||||
return null;
|
||||
@@ -228,6 +228,16 @@ namespace GameRes.Formats.Cyberworks
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual IndexReader GetIndexReader (byte[] toc, ArcView file, int arc_idx, string game_name)
|
||||
{
|
||||
return new ArcIndexReader (toc, file, arc_idx, game_name);
|
||||
}
|
||||
|
||||
internal virtual TocUnpacker GetTocUnpacker (string toc_name)
|
||||
{
|
||||
return new TocUnpacker (toc_name);
|
||||
}
|
||||
|
||||
internal ArcFile ArchiveFromDir (ArcView file, List<Entry> dir, bool has_images)
|
||||
{
|
||||
if (0 == dir.Count)
|
||||
@@ -245,7 +255,7 @@ namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
if (!VFS.FileExists (meta_arc_name))
|
||||
return null;
|
||||
using (var unpacker = new TocUnpacker (meta_arc_name))
|
||||
using (var unpacker = GetTocUnpacker (meta_arc_name))
|
||||
{
|
||||
if (unpacker.Length > 0x1000)
|
||||
return null;
|
||||
@@ -269,7 +279,7 @@ namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
if (!VFS.FileExists (toc_name))
|
||||
return null;
|
||||
using (var toc_unpacker = new TocUnpacker (toc_name))
|
||||
using (var toc_unpacker = GetTocUnpacker (toc_name))
|
||||
return toc_unpacker.Unpack (num_length);
|
||||
}
|
||||
|
||||
@@ -403,6 +413,26 @@ namespace GameRes.Formats.Cyberworks
|
||||
public AImageScheme Scheme;
|
||||
}
|
||||
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class DatOpener2024 : DatOpener
|
||||
{
|
||||
public override string Tag { get { return "ARC/Cyberworks/2"; } }
|
||||
public override string Description { get { return "Cyberworks/TinkerBell resource archive"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
internal override IndexReader GetIndexReader (byte[] toc, ArcView file, int arc_idx, string game_name)
|
||||
{
|
||||
return new ArcIndexReader2 (toc, file, arc_idx, game_name);
|
||||
}
|
||||
|
||||
internal override TocUnpacker GetTocUnpacker (string toc_name)
|
||||
{
|
||||
return new TocUnpacker (toc_name, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class OldDatOpener : DatOpener
|
||||
{
|
||||
@@ -514,19 +544,22 @@ namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
ArcView m_file;
|
||||
bool m_should_dispose;
|
||||
bool m_reversed_decimal;
|
||||
|
||||
public long Length { get { return m_file.MaxOffset; } }
|
||||
public uint PackedSize { get; private set; }
|
||||
public uint UnpackedSize { get; private set; }
|
||||
|
||||
public TocUnpacker (string toc_name) : this (VFS.OpenView (toc_name), true)
|
||||
public TocUnpacker (string toc_name, bool reversed_decimal = false)
|
||||
: this (VFS.OpenView (toc_name), true, reversed_decimal)
|
||||
{
|
||||
}
|
||||
|
||||
public TocUnpacker (ArcView file, bool should_dispose = false)
|
||||
public TocUnpacker (ArcView file, bool should_dispose = false, bool reversed_decimal = false)
|
||||
{
|
||||
m_file = file;
|
||||
m_should_dispose = should_dispose;
|
||||
m_reversed_decimal = reversed_decimal;
|
||||
}
|
||||
|
||||
public byte[] Unpack (int num_length)
|
||||
@@ -564,7 +597,22 @@ namespace GameRes.Formats.Cyberworks
|
||||
{
|
||||
uint v = 0;
|
||||
uint rank = 1;
|
||||
for (int i = num_length-1; i >= 0; --i, rank *= 10)
|
||||
|
||||
int start, end, step;
|
||||
if (m_reversed_decimal)
|
||||
{
|
||||
start = 0;
|
||||
end = num_length;
|
||||
step = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = num_length-1;
|
||||
end = -1;
|
||||
step = -1;
|
||||
}
|
||||
|
||||
for (int i = start; i != end; i += step, rank *= 10)
|
||||
{
|
||||
uint b = m_file.View.ReadByte (offset+i);
|
||||
if (b != 0xFF)
|
||||
@@ -627,9 +675,9 @@ namespace GameRes.Formats.Cyberworks
|
||||
return true;
|
||||
}
|
||||
|
||||
uint m_fault_id = 100000;
|
||||
protected uint m_fault_id = 100000;
|
||||
|
||||
internal PackedEntry ReadEntryInfo ()
|
||||
internal virtual PackedEntry ReadEntryInfo ()
|
||||
{
|
||||
uint id = m_index.ReadUInt32();
|
||||
if (id > m_fault_id)
|
||||
@@ -707,6 +755,27 @@ namespace GameRes.Formats.Cyberworks
|
||||
}
|
||||
}
|
||||
|
||||
internal class ArcIndexReader2 : ArcIndexReader
|
||||
{
|
||||
public ArcIndexReader2 (byte[] toc, ArcView file, int arc_number, string game_name = null)
|
||||
: base (toc, file, arc_number, game_name)
|
||||
{
|
||||
}
|
||||
|
||||
internal override PackedEntry ReadEntryInfo ()
|
||||
{
|
||||
uint id = m_index.ReadUInt32();
|
||||
if (id > m_fault_id)
|
||||
id = m_fault_id++;
|
||||
var entry = new PackedEntry { Name = id.ToString ("D6") };
|
||||
entry.UnpackedSize = m_index.ReadUInt32();
|
||||
entry.Offset = m_index.ReadUInt32();
|
||||
entry.Size = m_index.ReadUInt32();
|
||||
entry.IsPacked = entry.UnpackedSize != entry.Size && entry.UnpackedSize != 0;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
internal class DatIndexReader : IndexReader
|
||||
{
|
||||
public DatIndexReader (byte[] toc, ArcView file) : base (toc, file)
|
||||
|
||||
Reference in New Issue
Block a user