protected override TcdSection ReadSection(int number) { uint data_size = Input.ReadUInt32(); if (0 == data_size) { return(null); } var section = new TcdSection { DataSize = data_size }; section.Extension = Extensions[number]; section.FileCount = Input.ReadInt32(); section.DirCount = Input.ReadInt32(); section.IndexOffset = Input.ReadUInt32(); section.DirNameLength = Input.ReadInt32(); section.FileNameLength = Input.ReadInt32(); section.DirNamesSize = section.DirNameLength; section.FileNamesSize = section.FileNameLength; return(section); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } uint current_offset = 8; var sections = new List <TcdSection> (5); for (int i = 0; i < 5; ++i, current_offset += 0x20) { uint index_offset = file.View.ReadUInt32(current_offset + 4); if (0 == index_offset) { continue; } var section = new TcdSection { IndexOffset = index_offset, DataSize = file.View.ReadUInt32(current_offset), DirCount = file.View.ReadInt32(current_offset + 8), DirNameLength = file.View.ReadInt32(current_offset + 0x0C), FileCount = file.View.ReadInt32(current_offset + 0x10), FileNameLength = file.View.ReadInt32(current_offset + 0x14), }; sections.Add(section); } var list = new List <Entry> (count); foreach (var section in sections) { current_offset = section.IndexOffset; uint dir_size = (uint)(section.DirCount * section.DirNameLength); var dir_names = new byte[dir_size]; if (dir_size != file.View.Read(current_offset, dir_names, 0, dir_size)) { return(null); } current_offset += dir_size; DecryptNames(dir_names, section.DirNameLength); var dirs = new TcdDirEntry[section.DirCount]; for (int i = 0; i < dirs.Length; ++i) { dirs[i].FileCount = file.View.ReadInt32(current_offset); dirs[i].NamesOffset = file.View.ReadInt32(current_offset + 4); dirs[i].FirstIndex = file.View.ReadInt32(current_offset + 8); current_offset += 0x10; } uint entries_size = (uint)(section.FileCount * section.FileNameLength); var file_names = new byte[entries_size]; if (entries_size != file.View.Read(current_offset, file_names, 0, entries_size)) { return(null); } current_offset += entries_size; DecryptNames(file_names, section.FileNameLength); var offsets = new uint[section.FileCount + 1]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = file.View.ReadUInt32(current_offset); current_offset += 4; } int dir_name_offset = 0; foreach (var dir in dirs) { string dir_name = Binary.GetCString(dir_names, dir_name_offset, section.DirNameLength); dir_name_offset += section.DirNameLength; int index = dir.FirstIndex; int name_offset = dir.NamesOffset; for (int i = 0; i < dir.FileCount; ++i) { string name = Binary.GetCString(file_names, name_offset, section.FileNameLength); name_offset += section.FileNameLength; name = dir_name + '\\' + name; var entry = new TcdEntry(index, name, file, offsets[index]); entry.Size = offsets[index + 1] - offsets[index]; ++index; list.Add(entry); } } } return(new TcdArchive(file, this, list)); }