Exemple #1
0
        /// <summary>
        /// Read a single texture from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="texturesOffset">Offset to textures.</param>
        public BinTexture(DhBinaryReader br, long texturesOffset)
        {
            // Read texture width.
            Width = br.ReadU16();

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

            // Read texture format.
            Format = br.ReadU8();

            // Read texture unknown 1. (Flags?)
            Unknown1 = br.ReadU8();

            // Read texture unknown 2. (Padding)
            Unknown2 = br.ReadU16();

            // Read texture data offset.
            DataOffset = br.ReadU32();

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

            // Go to the bin textures offset.
            br.Goto(texturesOffset);

            // Sail to the texture's data offset.
            br.Sail(DataOffset);

            // Read the texture's raw data.
            Data = br.Read((Width * Height) / 2);

            // Go to the previously saved offset.
            br.Goto(currentPosition);
        }
Exemple #2
0
        /// <summary>
        /// Read a single entry from JMP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="fields">List of fields in JMP.</param>
        public JEntry(DhBinaryReader br, List <JField> fields)
        {
            long currentPosition = br.Position();

            Values = new Dictionary <string, object>();
            for (int i = 0; i < fields.Count; i++)
            {
                br.Sail(fields[i].Offset);

                object value;
                switch (fields[i].Type)
                {
                case JFieldType.INTEGER:
                    value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift);
                    break;

                case JFieldType.STRING:
                    value = br.ReadFixedStr(32);
                    break;

                case JFieldType.FLOAT:
                    value = br.ReadF32();
                    break;

                default:
                    throw new InvalidDataException($"{fields[i].Type} is not a valid jmp entry type!");
                }

                Values.Add(fields[i].Name, value);

                br.Goto(currentPosition);
            }
        }
Exemple #3
0
        /// <summary>
        /// Read a single entry from JMP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="fields">List of fields in JMP.</param>
        public JEntry(DhBinaryReader br, List <JField> fields)
        {
            // Save the current position.
            long currentPosition = br.Position();

            // Define a new object array to hold entry's values.
            Values = new object[fields.Count];

            // Loop through each field in the JMP.
            for (int i = 0; i < fields.Count; i++)
            {
                // Seek from the current position to value's offset in the entry.
                br.Sail(fields[i].Offset);

                // Define a new object to hold our data.
                object value;

                // Check which type the current value is.
                switch (fields[i].Type)
                {
                case JFieldType.INTEGER:
                    // Read the data as a integer.
                    value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift);
                    break;

                case JFieldType.STRING:
                    // Read the data as a 32-byte long string.
                    value = br.ReadStr32();
                    break;

                case JFieldType.FLOAT:
                    // Read the data as a float32.
                    value = br.ReadF32();
                    break;

                default:
                    // Something went horribly wrong.
                    throw new InvalidDataException();
                }
                // Set the value of this entry's value's data to the value we just read.
                Values[i] = value;

                // Seek back to the position we saved earlier.
                br.Goto(currentPosition);
            }
        }
Exemple #4
0
        /// <summary>
        /// Read a single triangle group from MP.
        /// </summary>
        /// <param name="br">The BinaryReader to read with.</param>
        public TriangleGroup(DhBinaryReader br)
        {
            // Define temporary list of ushorts to hold the indices.
            List <ushort> indices = new List <ushort>();

            // We'll read untill we read 0xFFFF, that means the end of this triangle group.
            while (br.ReadU16() != 0xFFFF)
            {
                // We'll go two bytes back, since we checked for 0xFFFF.
                br.Sail(-2);

                // Read a ushort, and add it to the list of indices.
                indices.Add(br.ReadU16());
            }

            // Set the indices array to the ones we've read.
            Indices = indices.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 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;
                }
            }
        }