Exemple #1
0
        /// <summary>
        /// Read a PrmEntry from PRM.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public PrmEntry(DhBinaryReader br)
        {
            // Read Hash.
            Hash = br.ReadU16();

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

            // Read Name.
            Name = br.ReadStr(NameLength);

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

            // Resolve Type from Hash.
            Type = PRMUtils.HashToType(Hash);

            // Check Type.
            switch (Type)
            {
            case PrmType.BYTE:

                // Read Value as a byte.
                Value = br.Read();
                break;

            case PrmType.SHORT:

                // Read Value as a short.
                Value = br.ReadS16();
                break;

            case PrmType.INT:

                // Read Value as a int.
                Value = br.ReadS32();
                break;

            case PrmType.FLOAT:

                // Read Value as a float.
                Value = br.ReadF32();
                break;

            case PrmType.RGBA:

                // Read Value as a Clr4.
                Value = br.ReadClr4();
                break;

            case PrmType.VECTOR3:

                // Read Value as a Vector3.
                Value = br.ReadVec3();
                break;

            default:
                throw new NotImplementedException("PRM parameter entry type is unknown!");
            }
        }
Exemple #2
0
        public static VirtDirectory LoadRarc(byte[] data)
        {
            if (Yay0.IsCompressed(data))
            {
                data = Yay0.Decompress(data);
            }

            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            if (br.ReadStr(4) != "RARC")
            {
                throw new InvalidDataException("No valid RARC signature was found!");
            }

            List <RarcNode>  nodes   = new List <RarcNode>();
            List <RarcEntry> entries = new List <RarcEntry>();

            // read header
            // RARC here
            br.Skip(4);
            br.Skip(4);
            var dataOffset = br.ReadU32() + 0x20;

            br.Skip(4);
            br.Skip(4);
            br.Skip(4);
            br.Skip(4);

            // read infoblock
            var NodeCount   = br.ReadU32();
            var NodeOffset  = br.ReadU32() + 0x20;
            var EntryCount  = br.ReadU32();
            var EntryOffset = br.ReadU32() + 0x20;

            br.Skip(4);
            var StringTableOffset = br.ReadU32() + 0x20;

            br.Skip(2);
            br.Skip(2);
            br.Skip(4);

            br.Goto(EntryOffset);

            // read entries
            for (int i = 0; i < EntryCount; i++)
            {
                RarcEntry entry = new RarcEntry()
                {
                    Id         = br.ReadU16(),
                    NameHash   = br.ReadU16(),
                    Type       = br.ReadU16(),
                    NameOffset = br.ReadU16(),
                    DataOffset = br.ReadU32(),
                    DataLength = br.ReadU32()
                };

                if (entry.Type == 0x1100)
                {
                    entry.Data = br.ReadAt(dataOffset + entry.DataOffset, (int)entry.DataLength);
                }
                entry.MemoryPointer = br.ReadU32();
                entry.Name          = br.ReadStrAt(StringTableOffset + entry.NameOffset);

                entries.Add(entry);
            }

            br.Goto(NodeOffset);

            // read nodes
            for (int i = 0; i < NodeCount; i++)
            {
                RarcNode rarcNode = new RarcNode()
                {
                    Id              = br.ReadStr(4),
                    NameOffset      = br.ReadU32(),
                    NameHash        = br.ReadU16(),
                    EntryCount      = br.ReadU16(),
                    FirstEntryIndex = br.ReadU32()
                };

                rarcNode.Name    = br.ReadStrAt(StringTableOffset + rarcNode.NameOffset);
                rarcNode.Entries = entries.GetRange((int)rarcNode.FirstEntryIndex, (int)rarcNode.EntryCount);

                nodes.Add(rarcNode);
            }

            List <VirtDirectory> virtDirectories = new List <VirtDirectory>(nodes.Count);

            foreach (RarcNode rarcNode in nodes)
            {
                virtDirectories.Add(new VirtDirectory(rarcNode.Name, Guid.Empty));
            }

            for (int i = 0; i < nodes.Count; i++)
            {
                RarcNode rarcNode = nodes[i];

                for (int y = 0; y < nodes[i].Entries.Count; y++)
                {
                    if (rarcNode.Entries[y].Name == "." || rarcNode.Entries[y].Name == "..")
                    {
                        continue;
                    }

                    if (rarcNode.Entries[y].Type == (ushort)NodeType.Directory)
                    {
                        var virtDirectory = virtDirectories[(int)rarcNode.Entries[y].DataOffset];
                        virtDirectory.ParentGuid = virtDirectories[i].Guid;
                        virtDirectory.Name       = rarcNode.Entries[y].Name;

                        virtDirectories[i].Children.Add(virtDirectory);
                    }
                    else
                    {
                        VirtFile virtFile = new VirtFile(rarcNode.Entries[y].Name, virtDirectories[i].Guid, rarcNode.Entries[y].Data);
                        virtDirectories[i].Children.Add(virtFile);
                    }
                }
            }

            return(virtDirectories.Count > 0 ? virtDirectories[0] : null);
        }
Exemple #3
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]));
            }
        }