Exemple #1
0
        /// <summary>
        /// Read a single vertex.
        /// </summary>
        /// <param name="br">The binaryreader to read with.</param>
        public Vertex(DhBinaryReader br, Attributes attributes, bool useNbt)
        {
            // Each vertex will always hold 26 indices. (Null = unused)
            Indices = new short?[26];

            // Get all the attributes from GX attributes.
            var indices = Enum.GetValues(typeof(Attributes));

            // Loop through GX attributes.
            for (int i = 0; i < indices.Length; i++)
            {
                // Make sure this attribute is present.
                if (attributes.HasFlag((Attributes)(1 << i)))
                {
                    // Read the current index.
                    Indices[i] = br.ReadS16();

                    // Check if we're reading normals and nbt is enabled.
                    if (i == 10 && useNbt)
                    {
                        // Set bitangent/tangent indices. (TODO - Fix the indices here...)
                        //Indices[24] = br.ReadS16();
                        //Indices[25] = br.ReadS16();
                        br.Skip(4); // Thanks to Astral-C for the tip of just throwing these away. (Until support is added)
                    }
                }
            }
        }
Exemple #2
0
 public MDLMaterial(DhBinaryReader br, List <MDLSampler> samplers)
 {
     DiffuseColor  = br.ReadClr4();
     Unknown1      = br.ReadS16();
     AlphaFlag     = br.ReadU8();
     TevStageCount = br.ReadU8();
     Unknown2      = br.ReadU8();
     br.Skip(23);
     TevStages = new List <MDLTevStage>();
     for (int i = 0; i < 8; i++)
     {
         TevStages.Add(new MDLTevStage(br));
     }
 }
Exemple #3
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 #4
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 #5
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 #6
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);
        }