Exemple #1
0
        /// <summary>
        /// Method for reading I8 encoded data.
        /// </summary>
        /// <param name="br">BinaryReader to read with.</param>
        /// <param name="width">Texture width.</param>
        /// <param name="height">Texture height.</param>
        /// <returns>Texture as a stream containing RGBA data.</returns>
        private static byte[] ReadI8(DhBinaryReader br, ushort width, ushort height)
        {
            // Buffer to store our decoded data.
            byte[] decoded = new byte[width * height * 4];

            // Loop through blocks y.
            for (int y = 0; y < (height / 4); y++)
            {
                // Loop through blocks y.
                for (int x = 0; x < (width / 8); x++)
                {
                    // Loop through pixels in block y.
                    for (int yx = 0; yx < 4; yx++)
                    {
                        // Loop through pixels in block y.
                        for (int xy = 0; xy < 8; xy++)
                        {
                            // Determine if pixel is oob (x || y).
                            if ((x * 8 + xy >= width) || (y * 4 + yx >= height))
                            {
                                // Skip.
                                continue;
                            }

                            // Read current pixel.
                            byte data = br.Read();

                            // Calculate offset for decoded data.
                            uint offset = (uint)(4 * (width * ((y * 4) + yx) + (x * 8) + xy));

                            // Store decoded data in buffer.
                            decoded[offset + 0] = data;
                            decoded[offset + 1] = data;
                            decoded[offset + 2] = data;
                            decoded[offset + 3] = 0xFF;
                        }
                    }
                }
            }

            // Return the texture as RGBA.
            return(decoded);
        }
Exemple #2
0
        private static byte[] ReadCMPR(DhBinaryReader br, uint width, uint height)
        {
            //Decode S3TC1
            byte[] buffer = new byte[width * height * 4];

            for (int y = 0; y < height / 4; y += 2)
            {
                for (int x = 0; x < width / 4; x += 2)
                {
                    for (int yx = 0; yx < 2; ++yx)
                    {
                        for (int xy = 0; xy < 2; ++xy)
                        {
                            if (4 * (x + xy) < width && 4 * (y + yx) < height)
                            {
                                byte[] fileData = br.Read(8);
                                //Array.Reverse(fileData);
                                Buffer.BlockCopy(fileData, 0, buffer, (int)(8 * ((y + yx) * width / 4 + x + xy)), 8);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < width * height / 2; i += 8)
            {
                // Micro swap routine needed
                Swap(ref buffer[i], ref buffer[i + 1]);
                Swap(ref buffer[i + 2], ref buffer[i + 3]);

                buffer[i + 4] = S3TC1ReverseByte(buffer[i + 4]);
                buffer[i + 5] = S3TC1ReverseByte(buffer[i + 5]);
                buffer[i + 6] = S3TC1ReverseByte(buffer[i + 6]);
                buffer[i + 7] = S3TC1ReverseByte(buffer[i + 7]);
            }

            //Now decompress the DXT1 data within it.
            return(DecompressDxt1(buffer, width, height));
        }
Exemple #3
0
        /// <summary>
        /// Reads BIN from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the BIN data.</param>
        public BIN(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read bin version.
            Version = br.Read();

            // Make sure the bin version is either 0x01 or 0x02.
            if (Version == 0x00 || Version > 0x02)
            {
                throw new Exception($"[BIN] {Version} is not a valid version!");
            }

            // Read bin model name.
            ModelName = br.ReadFixedStr(11);

            // Define a new list to hold the bin's offsets.
            Offsets = br.ReadU32s(21);

            // Go to the bin graph object offset.
            br.Goto(Offsets[12]);

            // Get first graph object, then all of it's attached graph objects.
            GraphObjects = GetGraphObjects(br, 0);


            // Make sure bin batches has a offset.
            if (Offsets[11] != 0)
            {
                // Go to the bin batches offset.
                br.Goto(Offsets[11]);

                // Define a new list to hold the bin's batches.
                Batches = new List <Batch>();

                // Loop through batches.
                for (int i = 0; i < GetBatchCount(); i++)
                {
                    // Read a batch and add it to the batch list.
                    Batches.Add(new Batch(br, Offsets[11]));
                }
            }


            // Make sure bin shaders has a offset.
            if (Offsets[10] != 0)
            {
                // Go to the bin shaders offset.
                br.Goto(Offsets[10]);

                // Define a new list to hold the bin's shaders.
                Shaders = new List <Shader>();

                // Loop through shaders.
                for (int i = 0; i < GetShaderCount(); i++)
                {
                    // Read a shader and add it to the shader list.
                    Shaders.Add(new Shader(br));
                }
            }


            // Make sure bin texture coordinates 1 has a offset.
            if (Offsets[7] != 0)
            {
                // Go to the bin texture coordinates 1 offset.
                br.Goto(Offsets[7]);

                // Define a new list to hold the bin's texture coordinates 1.
                TextureCoordinates1 = new List <Vec2>();

                // Loop through texture coordinates 1.
                for (int i = 0; i < GetTexCoordinate1Count(); i++)
                {
                    // Read a bin texture coordinates and add it to the texture coordinates 1 list.
                    TextureCoordinates1.Add(br.ReadVec2());
                }
            }


            // Make sure bin texture coordinates 0 has a offset.
            if (Offsets[6] != 0)
            {
                // Go to the bin texture coordinates 0 offset.
                br.Goto(Offsets[6]);

                // Define a new list to hold the bin's texture coordinates 0.
                TextureCoordinates0 = new List <Vec2>();

                // Loop through texture coordinates 0.
                for (int i = 0; i < GetTexCoordinate0Count(); i++)
                {
                    // Read a bin texture coordinates 0 and add it to the texture coordinates 0 list.
                    TextureCoordinates0.Add(br.ReadVec2());
                }
            }


            // WE'RE SKIPPING COLOR0 AND COLOR1! (Offset5 and Offset4)


            // Make sure bin normals has a offset.
            if (Offsets[3] != 0)
            {
                // Go to the bin normals offset.
                br.Goto(Offsets[3]);

                // Define a new list to hold the bin's normals.
                Normals = new List <Vec3>();

                // Loop through normals.
                for (int i = 0; i < GetNormalCount(); i++)
                {
                    // Read a bin normal and add it to the normals list.
                    Normals.Add(br.ReadVec3());
                }
            }


            // Make sure bin positions has a offset.
            if (Offsets[2] != 0)
            {
                // Go to the bin positions offset.
                br.Goto(Offsets[2]);

                // Define a new list to hold the bin's positions.
                Positions = new List <Vec3>();

                // Loop through positions.
                for (int i = 0; i < GetPositionCount(); i++)
                {
                    // Read a bin position and add it to the positions list.
                    Positions.Add(new Vec3(br.ReadF16() / 256.0f, br.ReadF16() / 256.0f, br.ReadF16() / 256.0f));
                }
            }


            // Make sure bin materials has a offset.
            if (Offsets[1] != 0)
            {
                // Go to the bin materials offset.
                br.Goto(Offsets[1]);

                // Define a new list to hold the bin's materials.
                Materials = new List <Material>();

                // Loop through materials.
                for (int i = 0; i < GetMaterialCount(); i++)
                {
                    // Read a bin material and add it to the materials list.
                    Materials.Add(new Material(br));
                }
            }


            // Make sure bin textures has a offset.
            if (Offsets[0] != 0)
            {
                // Go to the bin textures offset.
                br.Goto(Offsets[0]);

                // Define a new list to hold the bin's textures.
                Textures = new List <BTI>();

                // Loop through textures.
                for (int i = 0; i < GetTextureCount(); i++)
                {
                    // Read a bin textures and add it to the textures list.
                    Textures.Add(new BTI(br, Offsets[0]));
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Decompressing Yay0 compressed data. Full credits for this snippet goes to Daniel McCarthy:
        /// https://github.com/Daniel-McCarthy/Mr-Peeps-Compressor/blob/master/PeepsCompress/PeepsCompress/Algorithm%20Classes/YAY0.cs
        /// </summary>
        /// <param name="stream">Stream containing the Yay0 compressed data.</param>
        /// <returns>Decompressed data as a stream.</returns>
        public static Stream Decompress(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Define a list of bytes to hold the decompressed data.
            List <byte> output = new List <byte>();

            // Make sure the magic is "Yay0"
            if (br.ReadU32() != 1499560240)
            {
                throw new Exception("No valid Yay0 signature was found!");
            }
            int decompressedLength = br.ReadS32();
            int compressedOffset   = br.ReadS32();
            int decompressedOffset = br.ReadS32();
            int layoutBitsOffset;

            // Begin decompression.
            while (output.Count < decompressedLength)
            {
                // Define variable to hold the layout byte.
                byte LayoutByte = br.Read();
                // Define variable to hold the individual layout bits.
                BitArray LayoutBits = new BitArray(new byte[1] {
                    LayoutByte
                });

                // Loop through the layout bits.
                for (int i = 7; i > -1 && (output.Count < decompressedLength); i--)
                {
                    // The next layout bit is 1. (Uncompressed data)
                    if (LayoutBits[i] == true)
                    {
                        // Yay0 Non-compressed Data Chunk:
                        // Add one byte from decompressedOffset to decompressedData.

                        // Define variable to hold the current layout bits offset.
                        layoutBitsOffset = (int)stream.Position;

                        // Seek to the compressed data offset.
                        stream.Seek(decompressedOffset, SeekOrigin.Begin);

                        // Read a byte and add it to the list of output bytes.
                        output.Add(br.Read());

                        // Advance the decompressed offset by one byte.
                        decompressedOffset++;

                        // Return to the current layout bits offset.
                        stream.Seek(layoutBitsOffset, SeekOrigin.Begin);
                    }
                    // The next layout bit is 0. (Compressed data)
                    else
                    {
                        // Yay0 Compressed Data Chunk:
                        // Total length is 2 bytes.
                        // 4 bits = Length
                        // 12 bits = Offset

                        // Define variable to hold the current offset.
                        layoutBitsOffset = (int)stream.Position;

                        // Seek to the compressed data offset.
                        stream.Seek(compressedOffset, SeekOrigin.Begin);

                        // Read the first byte of the compressed data.
                        byte byte1 = br.Read();

                        // Read the second byte of the compressed data.
                        byte byte2 = br.Read();

                        // Advance the compressed data offset by 2 (Since we just read 2 bytes)
                        compressedOffset += 2;

                        // Get 4 upper bits of the first byte.
                        byte byte1Upper = (byte)((byte1 & 0x0F));

                        // Get 4 lower bits of the first byte.
                        byte byte1Lower = (byte)((byte1 & 0xF0) >> 4);

                        int finalOffset = ((byte1Upper << 8) | byte2) + 1;
                        int finalLength;

                        // Compressed chunk length is higher than 17.
                        if (byte1Lower == 0)
                        {
                            stream.Seek(decompressedOffset, SeekOrigin.Begin);
                            finalLength = br.Read() + 0x12;

                            // Advance the decompressed offset by one byte.
                            decompressedOffset++;
                        }
                        // Compressed chunk length is lower or equal to 17.
                        else
                        {
                            // The data chunk length is equals to the first byte's 4 lower bits + 2.
                            finalLength = byte1Lower + 2;
                        }

                        // Add data for finalLength iterations.
                        for (int j = 0; j < finalLength; j++)
                        {
                            // Add byte at offset (fileSize - finalOffset) to file.
                            output.Add(output[output.Count - finalOffset]);
                        }

                        // Return to the current layout bits offset.
                        stream.Seek(layoutBitsOffset, SeekOrigin.Begin);
                    }
                }
            }

            // Return decompressed data.
            return(new MemoryStream(output.ToArray()));
        }
Exemple #5
0
        /// <summary>
        /// Read a single batch from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="batchesOffset">Offset to batches.</param>
        public BinBatch(DhBinaryReader br, long batchesOffset)
        {
            // Read face count.
            FaceCount = br.ReadU16();

            // Read primitive list size.
            ListSize = (ushort)(br.ReadS16() << 5);

            // Read vertex attributes.
            VertexAttributes = (BinBatchAttributes)br.ReadU32();

            // Read UseNormals flag.
            UseNormals = br.Read();

            // Read Position Winding.
            Positions = br.Read();

            // Read UV Count.
            UvCount = br.Read();

            // Read UseNBT flag.
            UseNBT = br.Read();

            // Read Primitive offset.
            PrimitiveOffset = br.ReadU32();

            // Define array to hold Unknown 1 values.
            Unknown1 = new int[2];

            // Loop through Unknown 1 values.
            for (int i = 0; i < 2; i++)
            {
                // Read current Unknown 1 value.
                Unknown1[i] = br.ReadS32();
            }

            // Save the current position.
            long currentPosition = br.Position();

            // Go to the bin batches offset.
            br.Goto(batchesOffset);

            // Sail to the batches's primitive offset.
            br.Sail(PrimitiveOffset);

            // Define list to hold batch's primitives.
            Primitives = new List <BinPrimitive>();

            // Define int to hold amount of faces read.
            int readFaces = 0;

            // Read primitives until batch's face count has been reached.
            while (readFaces < FaceCount && br.Position() < (batchesOffset + PrimitiveOffset + ListSize))
            {
                // Read primitive.
                BinPrimitive binPrimitive = new BinPrimitive(br, UseNBT, UvCount, VertexAttributes);

                // Add the primitive to the batch's primitives.
                Primitives.Add(binPrimitive);

                // Add primitive's face count to the read faces counter.
                readFaces += binPrimitive.FaceCount;
            }

            // Go to the previously saved offset.
            br.Goto(currentPosition);
        }
Exemple #6
0
        /// <summary>
        /// Reads BIN from a stream.
        /// </summary>
        /// <param name="stream">The stream containing the BIN data.</param>
        public BIN(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read bin version.
            Version = br.Read();

            // Make sure the bin version is either 0x01 or 0x02.
            if (Version == 0x00 || Version > 0x02)
            {
                throw new Exception(string.Format("{0} is not a valid bin version!", Version.ToString()));
            }

            // Read bin model name.
            ModelName = br.ReadStr(11).Trim('\0');

            // Define a new list to hold the bin's offsets.
            Offsets = new List <uint>();

            // Loop through the bin's offsets.
            for (int i = 0; i < 21; i++)
            {
                // Read offset and add it to the offsets list.
                Offsets.Add(br.ReadU32());
            }


            // Go to the bin textures offset.
            br.Goto(Offsets[0]);

            // Define a new list to hold the bin's textures.
            Textures = new List <BinTexture>();

            // Loop through bin's textures. TODO: This is static for now, add automatic texture count.
            for (int i = 0; i < 3; i++)
            {
                // Read texture and add it to the textures list.
                Textures.Add(new BinTexture(br, Offsets[0]));
            }


            // Go to the bin materials offset.
            br.Goto(Offsets[1]);

            // Define a new list to hold the bin's materials.
            Materials = new List <BinMaterial>();

            // Loop through bin's materials. TODO: This is static for now, add automatic material count.
            for (int i = 0; i < 3; i++)
            {
                // Read texture and add it to the materials list.
                Materials.Add(new BinMaterial(br));
            }


            // Go to the bin positions offset.
            br.Goto(Offsets[2]);

            // Define a new list to hold the bin's positions.
            Positions = new List <Vector3>();

            // Loop through bin's positions. TODO: Fix this; This is a pretty shitty way to calculate amount of bin positions ...
            for (int i = 0; i < ((Math.Floor((decimal)(Offsets[3] - Offsets[2])) / 6) - 1); i++)
            {
                // Skip 6 bytes to "simulate" reading a bin position.
                br.Skip(6);

                // Make sure the currenet position has not passed the normals offset.
                if (!(br.Position() > Offsets[3]))
                {
                    // Go back 6 bytes as we just "simulated" to read a bin position.
                    br.Goto(br.Position() - 6);

                    // Read a position and add it to the positions list.
                    Positions.Add(new Vector3(br.ReadF16(), br.ReadF16(), br.ReadF16()));
                }
            }


            // Go to the bin normals offset.
            br.Goto(Offsets[3]);

            // Define a new list to hold the bin's normals.
            Normals = new List <Vector3>();

            // Loop through bin's normals. TODO: This is static for now, add automatic normal count.
            for (int i = 0; i < 69; i++)
            {
                // Read a normal and add it to the normals list.
                Normals.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()));
            }


            // Go to the bin texture coordinates offset.
            br.Goto(Offsets[6]);

            // Define a new list to hold the bin's texture coordinates.
            TextureCoordinates = new List <BinTextureCoordinate>();

            // Loop through bin's texture coordinates. TODO: This is static for now, add automatic texture coordinates count.
            for (int i = 0; i < 72; i++)
            {
                // Read a bin texture coordinates and add it to the texture coordinates list.
                TextureCoordinates.Add(new BinTextureCoordinate(br));
            }


            // Go to the bin shaders offset.
            br.Goto(Offsets[10]);

            // Define a new list to hold the bin's shaders.
            Shaders = new List <BinShader>();

            // Loop through bin's shaders. TODO: This is static for now, add automatic shader count.
            for (int i = 0; i < 3; i++)
            {
                // Read a bin shader and add it to the shaders list.
                Shaders.Add(new BinShader(br));
            }


            // Go to the bin batches offset.
            br.Goto(Offsets[11]);

            // Define a new list to hold the bin's batches.
            Batches = new List <BinBatch>();

            // Loop through bin's batches. TODO: This is static for now, add automatic batch count.
            for (int i = 0; i < 2; i++)
            {
                // Read a bin batch and add it to the batches list.
                Batches.Add(new BinBatch(br, Offsets[11]));
            }
        }
Exemple #7
0
        /// <summary>
        /// Reads BTI from a stream.
        /// </summary>
        /// <param name="stream">The stream containing the BTI data.</param>
        public BTI(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read Texture Format.
            Format = (TextureFormat)br.Read();

            // Read Alpha Flag.
            AlphaFlag = br.Read();

            // Read Width.
            Width = br.ReadU16();

            // Read Height.
            Height = br.ReadU16();

            // Read WrapS.
            WrapS = (WrapMode)br.Read();

            // Read WrapT.
            WrapT = (WrapMode)br.Read();

            // Read Palette Format.
            PaletteFormat = (PaletteFormat)br.ReadU16();

            // Read Palette Count.
            PaletteCount = br.ReadU16();

            // Read Palette Offset.
            PaletteOffset = br.ReadU32();

            // Read Unknown 1.
            Unknown1 = br.ReadU32();

            // Read MinFilterMode.
            MinFilterMode = (FilterMode)br.Read();

            // Read MagFilterMode.
            MagFilterMode = (FilterMode)br.Read();

            // Read MinLOD.
            MinLOD = br.ReadU16();

            // Read MagLOD.
            MagLOD = br.Read();

            // Read MipMap Count.
            MipMapCount = br.Read();

            // Read LodBias.
            LodBias = br.ReadU16();

            // Read DataOffset.
            DataOffset = br.ReadU32();

            // Read data.
            Data = br.Read((Width * Height) / 2);

            // Read Data.
            //Data = br.ReadAt(DataOffset, (Width * Height) / 4);
        }
Exemple #8
0
        /// <summary>
        /// Reads BTI using a BinaryReader. (BinTexture Format)
        /// </summary>
        /// <param name="br">The BinaryReader to use.</param>
        public BTI(DhBinaryReader br, uint textureOffset, uint textureLocationOffset)
        {
            // Set Texture Format.
            byte format = br.Read();

            // Texture Formats IDs are different in MDL's for some reason.
            switch (format)
            {
            case 3:
                Format = TextureFormat.I4;
                break;

            case 4:
                Format = TextureFormat.I8;
                break;

            case 6:
                Format = TextureFormat.IA8;
                break;

            case 7:
                Format = TextureFormat.RGB565;
                break;

            case 8:
                Format = TextureFormat.RGB5A3;
                break;

            case 10:
                Format = TextureFormat.CMPR;
                break;

            default:
                throw new Exception($"Texture format {format} is not supported yet!");
            }

            // Set Alpha Flag.
            AlphaFlag = br.Read();

            // Set Width.
            Width = br.ReadU16();

            // Set Height.
            Height = br.ReadU16();

            // Skip 26 bytes of padding.
            br.Skip(26);

            // Read data.
            int length = 0;

            switch (Format)
            {
            case TextureFormat.C4:
                length = Width * Height * 8;
                break;

            case TextureFormat.C8:
                length = Width * Height * 8;
                break;

            default:
                length = Width * Height * 4;
                break;
            }
            Data = br.Read(length);
        }
Exemple #9
0
        /// <summary>
        /// Reads BTI using a BinaryReader. (BinTexture Format)
        /// </summary>
        /// <param name="br">The BinaryReader to use.</param>
        public BTI(DhBinaryReader br, uint textureHeader)
        {
            // Set Width.
            Width = br.ReadU16();

            // Set Height.
            Height = br.ReadU16();

            // Set Texture Format.
            Format = (TextureFormat)br.Read();

            // Set Alpha Flag.
            AlphaFlag = br.Read();

            // Set WrapS.
            WrapS = WrapMode.ClampToEdge;

            // Set WrapT.
            WrapT = WrapMode.ClampToEdge;

            // Set Palette Format.
            PaletteFormat = PaletteFormat.RGB565;

            // Set Palette Count.
            PaletteCount = 0;

            // Set Palette Offset.
            PaletteOffset = 0;

            // Set Unknown 1. (Padding?)
            Unknown1 = 0;

            // Set MinFilterMode.
            MinFilterMode = FilterMode.Linear;

            // Set MagFilterMode.
            MagFilterMode = FilterMode.Linear;

            // Set MinLOD.
            MinLOD = 0;

            // Set MagLOD.
            MagLOD = 1;

            // Set MipMap Count.
            MipMapCount = 0;

            // Set LodBias.
            LodBias = 0;

            // Skip 2 bytes of padding.
            br.Skip(2);

            // Set Data Offset.
            DataOffset = br.ReadU32();

            // Read data.
            int length = 0;

            switch (Format)
            {
            case TextureFormat.C4:
                length = Width * Height * 8;
                break;

            case TextureFormat.C8:
                length = Width * Height * 8;
                break;

            default:
                length = Width * Height * 4;
                break;
            }
            Data = br.ReadAt((textureHeader) + DataOffset, length);
        }
Exemple #10
0
        /// <summary>
        /// Reads MP from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the MP data.</param>
        public MP(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read Grid Scale.
            GridScale = br.ReadVec3();

            // Read Minimum Bounds.
            MinimumBounds = br.ReadVec3();

            // Read Axis Lengths.
            AxisLengths = br.ReadVec3();

            // Define new array to hold offsets.
            Offsets = new int[7];

            // Loop through our offsets.
            for (int i = 0; i < 7; i++)
            {
                // Read offset and store it to the offsets array.
                Offsets[i] = br.ReadS32();
            }


            // Go to mp's vertex data offset.
            br.Goto(Offsets[0]);

            // Calculate amount of vertices.
            int verticeCount = (Offsets[1] - Offsets[0]) / 12;

            // Define new list to hold vertices.
            Vertices = new List <Vec3>();

            // Loop through vertices.
            for (int i = 0; i < verticeCount; i++)
            {
                // Read vertex and add it to the list of vertices.
                Vertices.Add(br.ReadVec3());
            }


            // Go to mp's normals offset.
            br.Goto(Offsets[1]);

            // Calculate amount of normals.
            int normalCount = (Offsets[2] - Offsets[1]) / 12;

            // Define new list to hold normals.
            Normals = new List <Vec3>();

            // Loop through normals.
            for (int i = 0; i < normalCount; i++)
            {
                // Read normal and add it to the normal list.
                Normals.Add(br.ReadVec3());
            }


            // Go to mp's triangle data offset.
            br.Goto(Offsets[2]);

            // Calculate amount of triangles.
            int triangleDataCount = (Offsets[3] - Offsets[2]) / 24;

            // Define new list to hold triangle data.
            TriangleData = new List <TriangleData>();

            // Loop through triangles.
            for (int i = 0; i < triangleDataCount; i++)
            {
                // Read triangle and add it to the triangle data list.
                TriangleData.Add(new TriangleData(br));
            }


            // Go to mp's triangle group offset.
            br.Goto(Offsets[3]);

            // Define new list to hold triangle groups.
            TriangleGroups = new List <TriangleGroup>();

            // Make sure first ushort is 0xFFFF.
            if (br.ReadU16() != 0xFFFF)
            {
                throw new FormatException("Start of triangle groups section was not 0xFFFF!");
            }

            // We'll read triangle groups as long as we're not entering the next section.
            while (br.Position() < Offsets[4] - 2)
            {
                // Read group and add it to the groups list.
                TriangleGroups.Add(new TriangleGroup(br));
            }

            // Make sure last ushort is 0xFFFF.
            if (br.ReadU16() != 0xFFFF)
            {
                throw new FormatException("End of triangle groups section was not 0xFFFF!");
            }

            // Go to mp's grid index offset.
            br.Goto(Offsets[4]);

            // Calculate amount of grid index entries. (Offset 5 is a duplicate of offset 4)
            int gridIndexCount = (Offsets[6] - Offsets[4]) / 8;

            // Define new list to hold grid indices.
            GridIndices = new List <GridIndex>();

            // Loop through grid indices.
            for (int i = 0; i < gridIndexCount; i++)
            {
                GridIndices.Add(new GridIndex(br));
            }


            // Go to mp's unknown offset.
            br.Goto(Offsets[6]);

            // Define new list to hold unknown data.
            Unknowns = new List <Unknown>();

            // We'll read unknowns as long as we're not reading padding EOF.
            while (br.Position() < br.GetStream().Length)
            {
                // Check if next byte is 0xFF. (More data)
                if (br.Read() == 0xFF)
                {
                    // Jump back a byte, since we checked for data.
                    br.Sail(-1);

                    // Read unknown and add it to the unknowns list.
                    Unknowns.Add(new Unknown(br));
                }
                else
                {
                    // We've reached padding, stop reading.
                    break;
                }
            }
        }
Exemple #11
0
 /// <summary>
 /// Read a single unknown from MP.
 /// </summary>
 /// <param name="br">The BinaryReader to read with.</param>
 public Unknown(DhBinaryReader br)
 {
     // Read unknown 1. (3 bytes)
     Unknown1 = br.Read(3);
 }