Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }