(PAC/LUNA): support 64-bit offsets.

This commit is contained in:
morkt 2019-01-27 02:28:21 +04:00
parent e24c01ad0f
commit 5d94af9cfa

View File

@ -45,23 +45,44 @@ namespace GameRes.Formats.LunaSoft
if (!IsSaneCount (count)) if (!IsSaneCount (count))
return null; return null;
long base_offset = file.View.ReadUInt32 (8); long base_offset = file.View.ReadUInt32 (8);
uint current_offset = 0x10;
var dir = new List<Entry> (count); var dir = new List<Entry> (count);
if (!ReadIndex (file, dir, count, base_offset) &&
!ReadIndex (file, dir, count, base_offset, true))
return null;
return new ArcFile (file, this, dir);
}
bool ReadIndex (ArcView file, List<Entry> dir, int count, long base_offset, bool long_offsets = false)
{
Func<uint, long> read_offset;
uint size_pos;
if (long_offsets)
{
read_offset = idx_off => file.View.ReadInt64 (idx_off);
size_pos = 0x108;
}
else
{
read_offset = idx_off => file.View.ReadUInt32 (idx_off);
size_pos = 0x104;
}
dir.Clear();
uint current_offset = 0x10;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
uint name_length = file.View.ReadUInt32 (current_offset+0x108); uint name_length = file.View.ReadUInt32 (current_offset+size_pos+4);
if (name_length > 0x100 || 0 == name_length)
return false;
var name = file.View.ReadString (current_offset, name_length); var name = file.View.ReadString (current_offset, name_length);
var entry = FormatCatalog.Instance.Create<Entry> (name); var entry = Create<Entry> (name);
current_offset += 0x100; entry.Offset = base_offset + read_offset (current_offset+0x100);
entry.Offset = base_offset + file.View.ReadUInt32 (current_offset); entry.Size = file.View.ReadUInt32 (current_offset+size_pos);
entry.Size = file.View.ReadUInt32 (current_offset+4);
if (!entry.CheckPlacement (file.MaxOffset)) if (!entry.CheckPlacement (file.MaxOffset))
return null; return false;
dir.Add (entry); dir.Add (entry);
current_offset += 0xC; current_offset += size_pos+8;
} }
return new ArcFile (file, this, dir); return true;
} }
} }
} }