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 TXP(Stream stream)
        {
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            //Ensure that Uknown 1 and 2 are 1 and 0 respectivley
            if (br.ReadU16() != 1)
            {
                throw new Exception("Unknown1 wasn't 1!");
            }

            if (br.ReadU16() != 0)
            {
                throw new Exception("Unknown2 wasn't 0!");
            }

            //Read the number of entries in the txp file
            ushort entryCount = br.ReadU16();

            //Read the number of frames in each entry
            FrameCount = br.ReadU16();

            //Skip unused frame offset
            br.ReadU32();

            TXPEntries = new List <TXPEntry>();

            for (int entry = 0; entry < entryCount; entry++)
            {
                TXPEntries.Add(new TXPEntry(br, FrameCount));
            }
        }
Exemple #3
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 #4
0
        /// <summary>
        /// Reads TXP from a data stream.
        /// </summary>
        /// <param name="stream">The stream containing the TXP data.</param>
        public TXP(Stream stream)
        {
            // Define a new binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

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

            // Read Unknown 2.
            Unknown2 = br.ReadU16();

            // Read Entry Count.
            EntryCount = br.ReadU16();

            // Read Keyframe Count.
            KeyFrameCount = br.ReadU16();

            // Read Keyframe Offset.
            KeyFrameOffset = br.ReadU32();

            // Initialize the list to hold our entries.
            Entries = new List <TxpEntry>();

            // Loop through entries.
            for (int i = 0; i < EntryCount; i++)
            {
                // Read entry.
                Entries.Add(new TxpEntry(br, KeyFrameCount));
            }
        }
Exemple #5
0
 public MDLSampler(DhBinaryReader br)
 {
     TextureIndex = br.ReadU16();
     UnknownIndex = br.ReadU16();
     WrapU        = (WrapMode)br.ReadU8();
     WrapV        = (WrapMode)br.ReadU8();
     MinFilter    = br.ReadU8();
     MagFilter    = br.ReadU8();
 }
Exemple #6
0
 public MDLShape(DhBinaryReader br, List <MDLShapePacket> packets)
 {
     NormalFlag       = br.ReadU8();
     Unknown1         = br.ReadU8();
     SurfaceFlag      = br.ReadU8();
     Unknown2         = br.ReadU8();
     PacketCount      = br.ReadU16();
     PacketBeginIndex = br.ReadU16();
     Packets          = packets.GetRange(PacketBeginIndex, PacketCount);
     UseNbt           = (NormalFlag > 0);
 }
Exemple #7
0
 public MDLNode(DhBinaryReader br, List <MDLDrawElement> drawElements)
 {
     MatrixIndex           = br.ReadU16();
     ChildIndex            = br.ReadU16();
     SiblingIndex          = br.ReadU16();
     Padding1              = br.ReadS16();
     DrawElementCount      = br.ReadU16();
     DrawElementBeginIndex = br.ReadU16();
     Padding2              = br.ReadS32();
     DrawElements          = drawElements.GetRange(DrawElementBeginIndex, DrawElementCount);
 }
Exemple #8
0
        public TXPEntry(DhBinaryReader br, ushort frameCount)
        {
            //Ensure that Uknown 1 is 1
            if (br.ReadU16() != 1)
            {
                throw new Exception("Unknown1 wasn't 1!");
            }

            //Read material index
            MaterialIndex = br.ReadS16();

            if (br.ReadU32() != 0)
            {
                throw new Exception("Unknown2 wasn't 0!");
            }

            //Read the frame data offset for this
            uint frameDataOffset = br.ReadU32();

            TexObjIndicies = new short[frameCount];

            //Save reader's current position and seek to the frame data
            br.SaveOffset(0);
            br.Goto(frameDataOffset);

            //Fill TexObjIndicies for each frame
            for (int frame = 0; frame < frameCount; frame++)
            {
                TexObjIndicies[frame] = br.ReadS16();
            }

            br.LoadOffset(0);
        }
Exemple #9
0
        /// <summary>
        /// Read a single sequence from TMB.
        /// </summary>
        /// <param name="br">The binary reader to read with.</param>
        public TMBSequence(DhBinaryReader br)
        {
            // Read name.
            Name = br.ReadFixedStr(28);

            // Read keyframe count.
            KeyFrameCount = br.ReadU32();

            // Read start index.
            StartIndex = br.ReadU16();

            // Read keyframe size.
            KeyFrameSize = br.ReadU16();

            // Define a new list to hold our keyframes.
            KeyFrames = new List <TIMKeyFrame>();
        }
Exemple #10
0
 /// <summary>
 /// Read a single field from JMP.
 /// </summary>
 /// <param name="br">Binary Reader to use.</param>
 public JField(DhBinaryReader br)
 {
     Hash    = br.ReadU32();
     Bitmask = br.ReadU32();
     Offset  = br.ReadU16();
     Shift   = br.ReadS8();
     Type    = (JFieldType)br.ReadU8();
     Name    = JMPUtils.HashToName(Hash);
 }
Exemple #11
0
        /// <summary>
        /// Read a single batch from BIN.
        /// </summary>
        /// <param name="br">The binaryreader to write with.</param>
        /// <param name="batchesOffset">Offset to batches.</param>
        public Batch(DhBinaryReader br, long batchesOffset)
        {
            // Read face count.
            FaceCount = br.ReadU16();

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

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

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

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

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

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

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

            // Read Unknown 1. (Padding?)
            Unknown1 = br.ReadS32s(2);

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

            // Go to the batch's primitive offset offset.
            br.Goto(batchesOffset + PrimitiveOffset);

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

            // Define int to keep track of the 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 << 5))))
            {
                // Read primitive.
                Primitive binPrimitive = new Primitive(br, VertexAttributes, UseNBT);

                // 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 #12
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 #13
0
 public MDLShapePacket(DhBinaryReader br)
 {
     DataOffset    = br.ReadU32();
     DataSize      = br.ReadU32();
     Unknown       = br.ReadS16();
     MatrixCount   = br.ReadU16();
     MatrixIndices = br.ReadU16s(10);
     PacketData    = new List <ShapePacketData>();
     Data          = br.ReadAt(DataOffset, (int)DataSize);
 }
Exemple #14
0
        /// <summary>
        /// Read a single texture from BIN.
        /// </summary>
        /// <param name="br">The BinaryReader to read with..</param>
        public UnusedTexture(DhBinaryReader br, uint textureOffset)
        {
            // Read texture width.
            Width = br.ReadU16();

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

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

            // Read texture alpha flag (Unsure, but seems logical)
            AlphaFlag = br.Read();

            // Read texture unknown 1. (Padding?)
            Unknown1 = 0;

            // Read texture data offset.
            DataOffset = br.ReadU32();
        }
Exemple #15
0
        /// <summary>
        /// Reads TMB from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the TMB data.</param>
        public TMB(byte[] data)
        {
            // Define a new binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read sequence count.
            SequenceCount = br.ReadU16();

            // Read timing duration.
            Duration = br.ReadU16();

            // Read sequence data offset.
            SequenceDataOffset = br.ReadU32();

            // Define a new list to hold our sequences.
            Sequences = new List <TMBSequence>();

            // Goto sequence data offset.
            br.Goto(SequenceDataOffset);

            // Loop through sequences within this bank.
            for (int i = 0; i < SequenceCount; i++)
            {
                // Read a sequence and add it to the list of sequences.
                Sequences.Add(new TMBSequence(br));
            }

            // Loop through sequences within this bank.
            for (int i = 0; i < SequenceCount; i++)
            {
                // Go to this sequence's keyframe data.
                br.Goto(8 + ((Sequences[i].StartIndex * 4)));

                // Loop through keyframe's within this sequence.
                for (int y = 0; y < Sequences[i].KeyFrameCount; y++)
                {
                    // Read this keyframe and add it to the sequence's list of the keyframes.
                    Sequences[i].KeyFrames.Add(new TIMKeyFrame(br, Sequences[i].KeyFrameSize));
                }
            }
        }
Exemple #16
0
 public MDLVertex(DhBinaryReader br, MDLHeader header, bool useNbt)
 {
     MatrixIndex     = br.ReadS8();
     Tex0MatrixIndex = br.ReadS8();
     Tex1MatrixIndex = br.ReadS8();
     PositionIndex   = br.ReadU16();
     if (header.NormalCount > 0)
     {
         NormalIndex = br.ReadU16();
     }
     if (useNbt)
     {
         //TangentIndex = br.ReadU16();
         //BiTangentIndex = br.ReadU16();
     }
     if (header.ColorCount > 0)
     {
         ColorIndex = br.ReadU16();
     }
     if (header.TextureCoordinateCount > 0)
     {
         TexCoordIndex = br.ReadU16();
     }
 }
Exemple #17
0
        private static byte[] ReadRGB565(DhBinaryReader br, uint width, uint height)
        {
            // Buffer to store our decoded data.
            byte[] decoded = new byte[width * height * 4];

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

                            // Calculate offset for decoded data.
                            int offset = (int)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 4) + pX));

                            // Read current pixel.
                            ushort pixel = br.ReadU16();

                            // Declare three bytes to hold our R, G, B components.
                            byte r = (byte)((((pixel & 0xF100) >> 11) << 3) | (((pixel & 0xF100) >> 11) >> 2));
                            byte g = (byte)((((pixel & 0x7E0) >> 5) << 2) | (((pixel & 0x7E0) >> 5) >> 4));
                            byte b = (byte)(((pixel & 0x1F) << 3) | ((pixel & 0x1F) >> 2));

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

            return(decoded);
        }
Exemple #18
0
        /// <summary>
        /// Read a single entry in TXP.
        /// </summary>
        /// <param name="br">The binaryreader to read with.</param>
        /// <param name="keyFrameCount">The amount of keyframes in each entry.</param>
        public TxpEntry(DhBinaryReader br, ushort keyFrameCount)
        {
            // Read Unknown 1.
            Unknown1 = br.ReadS16();

            //Read Material Index.
            MaterialIndex = br.ReadU16();

            // Read Unknown 2.
            Unknown2 = br.ReadS32();

            // Read Indices Offset.
            IndicesOffset = br.ReadU32();

            // Read Indices.
            Indices = br.ReadU16sAt(IndicesOffset, keyFrameCount).ToList();
        }
Exemple #19
0
        /// <summary>
        /// Method for reading IA8 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[] ReadIA8(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 x.
                for (int x = 0; x < (width / 4); x++)
                {
                    // Loop through pixels in block y.
                    for (int yx = 0; yx < 4; yx++)
                    {
                        // Loop through pixels in block x.
                        for (int xy = 0; xy < 4; xy++)
                        {
                            // Determine if pixel is oob (x || y).
                            if ((x * 4 + xy >= width) || (y * 4 + yx >= height))
                            {
                                // Skip.
                                continue;
                            }

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

                            // Read current pixel.
                            ushort data = br.ReadU16();

                            // Store decoded data in buffer.
                            decoded[offset + 3] = (byte)data;
                            decoded[offset + 2] = (byte)(data >> 8);
                            decoded[offset + 1] = (byte)(data >> 8);
                            decoded[offset + 0] = (byte)(data >> 8);
                        }
                    }
                }
            }

            // Return the texture as RGBA.
            return(decoded);
        }
Exemple #20
0
        /// <summary>
        /// Read a single field from JMP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public JField(DhBinaryReader br)
        {
            // Read field's hash.
            Hash = br.ReadU32();

            // Read field's bitmask.
            Bitmask = br.ReadU32();

            // Read field's offset.
            Offset = br.ReadU16();

            // Read field's shift.
            Shift = br.ReadS8();

            // Read field's type.
            Type = (JFieldType)br.ReadU8();

            // Resolve field's hash to get field name.
            Name = JMPUtils.HashToName(Hash);
        }
Exemple #21
0
        /// <summary>
        /// Reads BAS from a data stream.
        /// </summary>
        /// <param name="data">The byte array containing the BAS data.</param>
        public BAS(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read entry count.
            EntryCount = br.ReadU16();

            // Read unknown 1.
            Unknown1 = br.Read();

            // Read padding. (5 byte)
            Padding = br.Read(5);

            // Define a new list to hold the BAS entries.
            Entries = new List <BasEntry>();

            // Loop through the BAS entries.
            for (int i = 0; i < EntryCount; i++)
            {
                // Add the read entry to the Entries list.
                Entries.Add(new BasEntry(br));
            }
        }
Exemple #22
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 #23
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 #24
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 #25
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 #26
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 #27
0
        public MDL(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            Header = new MDLHeader(br);

            br.Goto(Header.MatricesOffset);
            Matrices = new Mat4[Header.JointCount + Header.WeightCount];
            for (int i = 0; i < Matrices.Length; i++)
            {
                Matrices[i] = Mat4.Identity;
            }

            for (int i = 0; i < Header.JointCount; i++)
            {
                float[] matrix = br.ReadF32s(12);

                Matrices[i] = new Mat4()
                {
                    Row1 = new Vec4(matrix[0], matrix[1], matrix[2], matrix[3]),
                    Row2 = new Vec4(matrix[4], matrix[5], matrix[6], matrix[7]),
                    Row3 = new Vec4(matrix[8], matrix[9], matrix[10], matrix[11]),
                    Row4 = new Vec4(0, 0, 0, 1),
                };
            }

            br.Goto(Header.PositionOffset);
            Positions = br.ReadVec3s(Header.PositionCount).ToList();

            br.Goto(Header.NormalOffset);
            Normals = br.ReadVec3s(Header.NormalCount).ToList();

            br.Goto(Header.ColorOffset);
            Colors = br.ReadClr4s(Header.ColorCount).ToList();

            br.Goto(Header.TextureCoordinateOffset);
            TextureCoordinates = br.ReadVec2s(Header.TextureCoordinateCount).ToList();

            br.Goto(Header.PacketOffset);
            Packets = new List <MDLShapePacket>();
            for (int i = 0; i < Header.PacketCount; i++)
            {
                Packets.Add(new MDLShapePacket(br));
            }

            br.Goto(Header.ShapeOffset);
            Shapes = new List <MDLShape>();
            for (int i = 0; i < Header.ShapeCount; i++)
            {
                Shapes.Add(new MDLShape(br, Packets));
            }

            foreach (MDLShape shape in Shapes)
            {
                ushort[] matrixIndices = new ushort[10];

                foreach (MDLShapePacket packet in shape.Packets)
                {
                    for (int m = 0; m < packet.MatrixCount; m++)
                    {
                        if (packet.MatrixIndices[m] == ushort.MaxValue)
                        {
                            continue;
                        }
                        matrixIndices[m] = packet.MatrixIndices[m];
                    }

                    DhBinaryReader reader = new DhBinaryReader(packet.Data, DhEndian.Big);

                    while (reader.Position() < packet.DataSize)
                    {
                        ShapePacketData packetData = new ShapePacketData();
                        packetData.PrimitiveType = reader.ReadU8();

                        if (packetData.PrimitiveType == 0x00)
                        {
                            continue;
                        }

                        packetData.VertexCount = reader.ReadU16();
                        for (int i = 0; i < packetData.VertexCount; i++)
                        {
                            MDLVertex vertex = new MDLVertex(reader, Header, shape.UseNbt);
                            if (vertex.MatrixIndex != -1)
                            {
                                vertex.MatrixDataIndex = matrixIndices[(vertex.MatrixIndex / 3)];
                            }
                            packetData.Vertices.Add(vertex);
                        }
                        packet.PacketData.Add(packetData);
                    }
                }
            }

            br.Goto(Header.TextureLocationOffset);
            Textures = new List <BTI>();
            for (int i = 0; i < Header.TextureCount; i++)
            {
                uint offset          = br.ReadU32();
                long currentPosition = br.Position();
                br.Goto(offset);
                BTI bti = new BTI(br, offset, Header.TextureLocationOffset);
                Textures.Add(bti);
                br.Goto(currentPosition);
            }

            br.Goto(Header.SamplerOffset);
            Samplers = new List <MDLSampler>();
            for (int i = 0; i < Header.SamplerCount; i++)
            {
                Samplers.Add(new MDLSampler(br));
            }

            br.Goto(Header.MaterialOffset);
            Materials = new List <MDLMaterial>();
            for (int i = 0; i < Header.MaterialCount; i++)
            {
                Materials.Add(new MDLMaterial(br, Samplers));
            }

            br.Goto(Header.DrawElementOffset);
            DrawElements = new List <MDLDrawElement>();
            for (int i = 0; i < Header.DrawElementCount; i++)
            {
                DrawElements.Add(new MDLDrawElement(br, Materials, Shapes));
            }

            br.Goto(Header.NodeOffset);
            Nodes = new List <MDLNode>();
            for (int i = 0; i < Header.NodeCount; i++)
            {
                Nodes.Add(new MDLNode(br, DrawElements));
            }
        }
Exemple #28
0
        /// <summary>
        /// Method for reading RBG5A3 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[] ReadRGB5A3(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 x.
                for (int x = 0; x < (width / 4); x++)
                {
                    // Loop through pixels in block y.
                    for (int yx = 0; yx < 4; yx++)
                    {
                        // Loop through pixels in block x.
                        for (int xy = 0; xy < 4; xy++)
                        {
                            // Determine if pixel is oob (x || y).
                            if ((x * 4 + xy >= width) || (y * 4 + yx >= height))
                            {
                                // Skip.
                                continue;
                            }

                            // Read current pixel.
                            ushort pixel = br.ReadU16();

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

                            // Declare four bytes to hold our R, G, B, A components.
                            byte r, g, b, a;

                            // Determine if there is any alpha bits.
                            if ((pixel & 0x8000) == 0x8000)
                            {
                                // Alpha component. (No Alpha)
                                a = 0xFF;

                                // Red component.
                                r = (byte)((pixel & 0x7C00) >> 10);
                                r = (byte)((r << 3) | (r >> 2));

                                // Green component.
                                g = (byte)((pixel & 0x3E0) >> 5);
                                g = (byte)((g << 3) | (g >> 2));

                                // Blue component.
                                b = (byte)(pixel & 0x1F);
                                b = (byte)((b << 3) | (b >> 2));
                            }
                            else
                            {
                                // Alpha component.
                                a = (byte)((pixel & 0x7000) >> 12);
                                a = (byte)((a << 2) | (a << 2) | (a >> 1));

                                // Red component.
                                r = (byte)((pixel & 0xF00) >> 8);
                                r = (byte)((r << 4) | r);

                                // Green component.
                                g = (byte)((pixel & 0xF0) >> 4);
                                g = (byte)((g << 4) | g);

                                // Blue component.
                                b = (byte)(pixel & 0xF);
                                b = (byte)((b << 4) | b);
                            }

                            // Store decoded data in buffer.
                            decoded[offset + 0] = a;
                            decoded[offset + 1] = b;
                            decoded[offset + 2] = g;
                            decoded[offset + 3] = r;
                        }
                    }
                }
            }

            // Return the texture as RGBA.
            return(decoded);
        }
Exemple #29
0
        /// <summary>
        /// Read a single graph object from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="graphObjectOffset">Offset to the graph objects.</param>
        public GraphObject(DhBinaryReader br, uint graphObjectOffset) // 112 bytes long
        {
            // Read Parent Index.
            ParentIndex = br.ReadS16();

            // Read Child Index.
            ChildIndex = br.ReadS16();

            // Read Next Index.
            NextIndex = br.ReadS16();

            // Read Previous Index.
            PreviousIndex = br.ReadS16();

            // Read Render Flags.
            RenderFlags = (GraphObjectRenderFlags)br.ReadU16();

            // Unknown 1. (Padding?)
            Unknown1 = br.ReadU16();

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

            // Read Rotation.
            Rotation = br.ReadVec3();

            // Read Position
            Position = br.ReadVec3();

            // Read Bounding Box Minimum.
            BoundingBoxMinimum = br.ReadVec3();

            // Read Bounding Box Maximum.
            BoundingBoxMaximum = br.ReadVec3();

            // Read Bounding Sphere Radius.
            BoundingSphereRadius = br.ReadF32();

            // Read Parent Index.
            PartCount = br.ReadS16();

            // Unknown 3. (Padding?)
            Unknown3 = br.ReadU16();

            // Read Parent Index.
            PartOffset = br.ReadS32();

            // Unknown 4. (Padding?)
            Unknown4 = br.ReadU32s(7);

            // Initialize a new list to hold parts.
            Parts = new List <BinGraphObjectPart>();

            // Offset to continue reading from.
            long currentPosition = br.Position();

            // Goto graphobject's parts.
            br.Goto(graphObjectOffset + PartOffset);

            // Loop through parts.
            for (int i = 0; i < PartCount; i++)
            {
                // Read part and add it to the list of parts.
                Parts.Add(new BinGraphObjectPart(br));
            }

            // Go back to return offset we saved earlier.
            br.Goto(currentPosition);
        }
Exemple #30
0
        public MDLHeader(DhBinaryReader br)
        {
            // magic
            Magic = br.ReadU32();

            // counts
            FaceCount              = br.ReadU16();
            Padding                = br.ReadS16();
            NodeCount              = br.ReadU16();
            PacketCount            = br.ReadU16();
            WeightCount            = br.ReadU16();
            JointCount             = br.ReadU16();
            PositionCount          = br.ReadU16();
            NormalCount            = br.ReadU16();
            ColorCount             = br.ReadU16();
            TextureCoordinateCount = br.ReadU16();
            Padding2               = br.ReadS64();
            TextureCount           = br.ReadU16();
            Padding3               = br.ReadS16();
            SamplerCount           = br.ReadU16();
            DrawElementCount       = br.ReadU16();
            MaterialCount          = br.ReadU16();
            ShapeCount             = br.ReadU16();
            Padding4               = br.ReadS32();

            // offsets
            NodeOffset              = br.ReadU32();
            PacketOffset            = br.ReadU32();
            MatricesOffset          = br.ReadU32();
            WeightOffset            = br.ReadU32();
            JointOffset             = br.ReadU32();
            WeightCountTableOffset  = br.ReadU32();
            PositionOffset          = br.ReadU32();
            NormalOffset            = br.ReadU32();
            ColorOffset             = br.ReadU32();
            TextureCoordinateOffset = br.ReadU32();
            Padding5 = br.ReadS64();
            TextureLocationOffset = br.ReadU32();
            Padding6          = br.ReadS32();
            MaterialOffset    = br.ReadU32();
            SamplerOffset     = br.ReadU32();
            ShapeOffset       = br.ReadU32();
            DrawElementOffset = br.ReadU32();
            Padding7          = br.ReadS64();
        }