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);
|
var toc = ReadToc (toc_name, 8);
|
||||||
if (null == toc)
|
if (null == toc)
|
||||||
return null;
|
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())
|
if (!index.Read())
|
||||||
return null;
|
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)
|
internal ArcFile ArchiveFromDir (ArcView file, List<Entry> dir, bool has_images)
|
||||||
{
|
{
|
||||||
if (0 == dir.Count)
|
if (0 == dir.Count)
|
||||||
@@ -245,7 +255,7 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
{
|
{
|
||||||
if (!VFS.FileExists (meta_arc_name))
|
if (!VFS.FileExists (meta_arc_name))
|
||||||
return null;
|
return null;
|
||||||
using (var unpacker = new TocUnpacker (meta_arc_name))
|
using (var unpacker = GetTocUnpacker (meta_arc_name))
|
||||||
{
|
{
|
||||||
if (unpacker.Length > 0x1000)
|
if (unpacker.Length > 0x1000)
|
||||||
return null;
|
return null;
|
||||||
@@ -269,7 +279,7 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
{
|
{
|
||||||
if (!VFS.FileExists (toc_name))
|
if (!VFS.FileExists (toc_name))
|
||||||
return null;
|
return null;
|
||||||
using (var toc_unpacker = new TocUnpacker (toc_name))
|
using (var toc_unpacker = GetTocUnpacker (toc_name))
|
||||||
return toc_unpacker.Unpack (num_length);
|
return toc_unpacker.Unpack (num_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,6 +413,26 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
public AImageScheme Scheme;
|
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))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
public class OldDatOpener : DatOpener
|
public class OldDatOpener : DatOpener
|
||||||
{
|
{
|
||||||
@@ -514,19 +544,22 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
{
|
{
|
||||||
ArcView m_file;
|
ArcView m_file;
|
||||||
bool m_should_dispose;
|
bool m_should_dispose;
|
||||||
|
bool m_reversed_decimal;
|
||||||
|
|
||||||
public long Length { get { return m_file.MaxOffset; } }
|
public long Length { get { return m_file.MaxOffset; } }
|
||||||
public uint PackedSize { get; private set; }
|
public uint PackedSize { get; private set; }
|
||||||
public uint UnpackedSize { 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_file = file;
|
||||||
m_should_dispose = should_dispose;
|
m_should_dispose = should_dispose;
|
||||||
|
m_reversed_decimal = reversed_decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] Unpack (int num_length)
|
public byte[] Unpack (int num_length)
|
||||||
@@ -564,7 +597,22 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
{
|
{
|
||||||
uint v = 0;
|
uint v = 0;
|
||||||
uint rank = 1;
|
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);
|
uint b = m_file.View.ReadByte (offset+i);
|
||||||
if (b != 0xFF)
|
if (b != 0xFF)
|
||||||
@@ -627,9 +675,9 @@ namespace GameRes.Formats.Cyberworks
|
|||||||
return true;
|
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();
|
uint id = m_index.ReadUInt32();
|
||||||
if (id > m_fault_id)
|
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
|
internal class DatIndexReader : IndexReader
|
||||||
{
|
{
|
||||||
public DatIndexReader (byte[] toc, ArcView file) : base (toc, file)
|
public DatIndexReader (byte[] toc, ArcView file) : base (toc, file)
|
||||||
|
|||||||
Reference in New Issue
Block a user