public List <M3ArchiveFileEntry> ExtractFileEntriesFromArchive(byte[] headerData, bool containsSubFolders = true) { List <M3ArchiveFileEntry> entries = new List <M3ArchiveFileEntry>(); int headerIndex = sizeof(UInt32); int metaDataStartIndex; byte[] folderNameBytes; string folderName = ""; M3ArchiveFileEntry entry; while (headerIndex + sizeof(UInt32) < headerData.Length) { if (containsSubFolders) { folderNameBytes = headerData.Skip(headerIndex).Take(sizeof(UInt32)).ToArray(); folderName = Encoding.ASCII.GetString(folderNameBytes); headerIndex += sizeof(UInt32); } // directoryIndex is stored as 24 bit int UInt16 part = BitConverter.ToUInt16(headerData, headerIndex); uint directoryIndex = (uint)(part | (headerData[headerIndex + 2] << 16)); uint subItemCount = headerData[headerIndex + 3]; headerIndex += sizeof(UInt32); for (int i = 0; i < subItemCount; i++) { // READ VALUES entry = new M3ArchiveFileEntry(); entry.Folder = folderName; entry.Offset = BitConverter.ToUInt32(headerData, headerIndex); headerIndex += sizeof(UInt32); entry.Size = BitConverter.ToUInt32(headerData, headerIndex); headerIndex += sizeof(UInt32); entry.MetaDataSize = BitConverter.ToUInt16(headerData, headerIndex); headerIndex += sizeof(UInt16); entry.CubeFace = (M3CubeFace)headerData[headerIndex]; headerIndex += sizeof(byte); entry.Type = (Myst3ResourceType)headerData[headerIndex]; headerIndex += sizeof(byte); metaDataStartIndex = headerIndex; headerIndex += (sizeof(UInt32) * entry.MetaDataSize); entry.MetaData = new byte[sizeof(UInt32) * entry.MetaDataSize]; Array.Copy(headerData, metaDataStartIndex, entry.MetaData, 0, sizeof(UInt32) * entry.MetaDataSize); ReadMetaData(entry); entries.Add(entry); } } return(entries); }
private void ReadMetaData(M3ArchiveFileEntry entry) { // MAKE USE OF META DATA if (entry.MetaDataSize == 2 && (entry.Type == Myst3ResourceType.SpotItem || entry.Type == Myst3ResourceType.LocalizedSpotItem)) { // create SpotItemData entry.SpotItemData.U = BitConverter.ToUInt32(entry.MetaData, 0); entry.SpotItemData.V = BitConverter.ToUInt32(entry.MetaData, sizeof(UInt32)); } else if (entry.MetaDataSize == 10 && (entry.Type == Myst3ResourceType.Movie || entry.Type == Myst3ResourceType.MultitrackMovie)) { // create VideoData } else if (entry.Type == Myst3ResourceType.NumMetadata || entry.Type == Myst3ResourceType.TextMetadata) { // copy metadata to something accessible to this item } else if (entry.MetaDataSize != 0) { //throw new Exception("Metadata not read for type " + resType + " size: " + metaDataSize); } }