private bool ReadBND1(BinaryReader2 br) { br.BigEndian = true; // Version number? br.ReadUInt32(); uint entryCount = br.ReadUInt32(); uint[] dataBlockSizes = new uint[5]; for (int i = 0; i < dataBlockSizes.Length; i++) { dataBlockSizes[i] = br.ReadUInt32(); br.BaseStream.Position += 4; // Padding } br.BaseStream.Position += 0x14; // Unknown Data uint idListOffset = br.ReadUInt32(); uint idTableOffset = br.ReadUInt32(); br.ReadUInt32(); // dependency block br.ReadUInt32(); // start of data block Platform = BundlePlatform.X360; // Xbox only for now br.ReadUInt32(); // might be platform (2 being X360) uint compressed = br.ReadUInt32(); if (compressed != 0) { Flags = Flags.Compressed; // TODO } else { Flags = 0; } br.ReadUInt32(); // unknown purpose sometimes the same as entryCount uint uncompressedInfoOffset = br.ReadUInt32(); br.ReadUInt32(); // main memory alignment br.ReadUInt32(); // graphics memory alignment Entries.Clear(); br.BaseStream.Position = idListOffset; List <ulong> resourceIds = new List <ulong>(); for (int i = 0; i < entryCount; i++) { resourceIds.Add(br.ReadUInt64()); } br.BaseStream.Position = idTableOffset; foreach (ulong resourceId in resourceIds) { BundleEntry entry = new BundleEntry(this); entry.EntryBlocks = new EntryBlock[3]; entry.ID = resourceId; br.ReadUInt32(); // unknown mem stuff entry.DependenciesListOffset = br.ReadInt32(); entry.Type = (EntryType)br.ReadUInt32(); //uint[] sizes = new uint[2]; if (compressed != 0) { //sizes[0] = br.ReadUInt32(); entry.EntryBlocks[0] = new EntryBlock(); entry.EntryBlocks[0].Compressed = true; entry.EntryBlocks[0].CompressedSize = br.ReadUInt32(); br.ReadUInt32(); // Alignment value, should be 1 br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value, should be 1 //sizes[1] = br.ReadUInt32(); entry.EntryBlocks[1] = new EntryBlock(); entry.EntryBlocks[1].Compressed = true; entry.EntryBlocks[1].CompressedSize = br.ReadUInt32(); br.ReadUInt32(); // Alignment value, should be 1 br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value, should be 1 br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value, should be 1 } else { //sizes[0] = br.ReadUInt32(); entry.EntryBlocks[0] = new EntryBlock(); entry.EntryBlocks[0].Compressed = false; entry.EntryBlocks[0].UncompressedSize = br.ReadUInt32(); entry.EntryBlocks[0].UncompressedAlignment = br.ReadUInt32(); br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value //sizes[1] = br.ReadUInt32(); entry.EntryBlocks[1] = new EntryBlock(); entry.EntryBlocks[1].Compressed = false; entry.EntryBlocks[1].UncompressedSize = br.ReadUInt32(); entry.EntryBlocks[1].UncompressedAlignment = br.ReadUInt32(); br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value } uint dataBlockStartOffset = 0; for (int j = 0; j < dataBlockSizes.Length; j++) { if (j > 0) { dataBlockStartOffset += dataBlockSizes[j - 1]; } uint readOffset = br.ReadUInt32() + dataBlockStartOffset; br.ReadUInt32(); // 1 if (j != 0 && j != 2) { continue; // Not supporting blocks 2, 4 and 5 right now. } int mappedBlock = j; if (j == 2) { mappedBlock = 1; } if (entry.EntryBlocks[mappedBlock] == null) { entry.EntryBlocks[mappedBlock] = new EntryBlock(); } EntryBlock entryBlock = entry.EntryBlocks[mappedBlock]; //uint readSize = sizes[mappedBlock]; uint readSize = compressed != 0 ? entryBlock.CompressedSize : entryBlock.UncompressedSize; if (readSize == 0) { entryBlock.RawData = null; continue; } long pos = br.BaseStream.Position; br.BaseStream.Position = readOffset; entryBlock.RawData = br.ReadBytes((int)readSize); br.BaseStream.Position = pos; } br.BaseStream.Position += 0x14; // unknown mem stuff Entries.Add(entry); } if (compressed != 0) { br.BaseStream.Position = uncompressedInfoOffset; for (int i = 0; i < Entries.Count; i++) { BundleEntry entry = Entries[i]; //uint[] sizes = new uint[2]; //sizes[0] = br.ReadUInt32(); entry.EntryBlocks[0].UncompressedSize = br.ReadUInt32(); entry.EntryBlocks[0].UncompressedAlignment = br.ReadUInt32(); br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value //sizes[1] = br.ReadUInt32(); entry.EntryBlocks[1].UncompressedSize = br.ReadUInt32(); entry.EntryBlocks[1].UncompressedAlignment = br.ReadUInt32(); br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value br.ReadUInt32(); // other blocks. Maybe used but I'm ignoring it. br.ReadUInt32(); // Alignment value //for (int j = 0; j < 2; j++) //{ // EntryBlock entryBlock = entry.EntryBlocks[j]; // if (sizes[j] > 0) // entryBlock.Data = entryBlock.Data.Decompress((int)sizes[j]); //} } } for (int i = 0; i < Entries.Count; i++) { BundleEntry entry = Entries[i]; uint depOffset = (uint)entry.DependenciesListOffset; if (depOffset == 0) { continue; } br.BaseStream.Position = depOffset; entry.DependencyCount = (short)br.ReadUInt32(); if (br.ReadUInt32() != 0) { return(false); } for (int j = 0; j < entry.DependencyCount; j++) { Dependency dep = new Dependency(); dep.ID = br.ReadUInt64(); dep.EntryPointerOffset = br.ReadUInt32(); br.ReadUInt32(); // Skip entry.Dependencies.Add(dep); } } BundleEntry rst = GetEntryByID(0xC039284A); if (rst == null) { return(true); } BinaryReader2 br2 = new BinaryReader2(rst.MakeStream()); br2.BigEndian = false; // TODO: Store only the debug info and not the full string ResourceStringTable = br2.ReadLenString(); br2.Close(); // Cover Criterion's broken XML writer. if (ResourceStringTable.StartsWith("</ResourceStringTable>")) { ResourceStringTable = ResourceStringTable.Remove(1, 1); } string badLine = "</ResourceStringTable>\n\t"; int index = ResourceStringTable.IndexOf(badLine); if (index > -1) { ResourceStringTable = ResourceStringTable.Remove(index, badLine.Length); } ProcessRST(ResourceStringTable); Entries.Remove(rst); return(true); }
public static VertexDesc Read(BundleEntry entry) { VertexDesc result = new VertexDesc(); MemoryStream ms = entry.MakeStream(); BinaryReader2 br = new BinaryReader2(ms); br.BigEndian = entry.Console; result.Unknown1 = br.ReadInt32(); result.Unknown2 = br.ReadInt32(); result.Unknown3 = br.ReadInt32(); result.AttributeCount = br.ReadInt32(); for (int i = 0; i < result.AttributeCount; i++) { VertexAttribute attribute = new VertexAttribute(); if (result.Unknown2 != 0) // BPR { attribute.Type = (VertexAttributeType)br.ReadInt32(); if (!Enum.IsDefined(typeof(VertexAttributeType), attribute.Type)) { MessageBox.Show("Unknown vertex attribute type: " + attribute.Type); } attribute.Unknown1 = br.ReadUInt32(); attribute.Offset = br.ReadUInt32(); attribute.Unknown2 = br.ReadUInt32(); attribute.Size = br.ReadUInt32(); } else { br.BaseStream.Position += 1; attribute.Size = br.ReadByte(); attribute.Offset = br.ReadByte(); // These are probably in the following bytes but I'll need to check where. attribute.Unknown1 = 0; attribute.Unknown2 = 0; br.BaseStream.Position += 8; byte type = br.ReadByte(); switch (type) { case 1: attribute.Type = VertexAttributeType.Positions; break; case 3: attribute.Type = VertexAttributeType.Normals; break; case 6: attribute.Type = VertexAttributeType.UV1; break; case 7: attribute.Type = VertexAttributeType.UV2; break; case 14: attribute.Type = VertexAttributeType.BoneIndexes; break; case 15: attribute.Type = VertexAttributeType.BoneWeights; break; case 21: attribute.Type = VertexAttributeType.Tangents; break; default: attribute.Type = VertexAttributeType.Invalid; MessageBox.Show("Unknown vertex attribute type: " + type); break; } br.BaseStream.Position += 4; } result.Attributes.Add(attribute); } br.Close(); ms.Close(); return(result); }