Esempio n. 1
0
        /// <summary>
        /// Method for reading RGBA32 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[] ReadRGBA32(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 subblock 1 y.
                    for (int yx = 0; yx < 4; yx++)
                    {
                        // Loop through subblock 1 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));

                            // Store decoded Alpha, Red subblock data in buffer.
                            decoded[offset + 3] = br.Read();
                            decoded[offset + 2] = br.Read();
                        }
                    }

                    // Loop through subblock 2 y.
                    for (int yx = 0; yx < 4; yx++)
                    {
                        // Loop through subblock 2 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));

                            // Store decoded Green, Blue subblock data in buffer.
                            decoded[offset + 1] = br.Read();
                            decoded[offset + 0] = br.Read();
                        }
                    }
                }
            }

            // Return the texture as RGBA.
            return(decoded);
        }
Esempio n. 2
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));
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        /// <summary>
        /// Read a single entry from BAS.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public BasEntry(DhBinaryReader br)
        {
            // Read Id.
            Id = br.ReadU32();

            // Read Gain.
            Gain = br.ReadF32();

            // Read Delay / Length.
            Delay = br.ReadF32();

            // Read Pitch.
            Pitch = br.ReadF32();

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

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

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

            // Read Unknown 3.
            Unknown3 = br.Read();

            // Read Unknown 4.
            Unknown4 = br.Read();

            // Read Padding.
            Padding = br.ReadU32s(2);
        }
Esempio n. 5
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!");
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Reads JMP from a data stream.
        /// </summary>
        /// <param name="stream">The stream containing the JMP data.</param>
        public JMP(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read JMP's Header
            uint entryCount = br.ReadU32();
            uint fieldCount = br.ReadU32();

            EntryOffset = br.ReadU32();
            EntrySize   = br.ReadU32();

            // Read JMP's Fields
            Fields = new List <JField>();
            for (int i = 0; i < fieldCount; i++)
            {
                Fields.Add(new JField(br));
            }

            // Seek to beginning of file.
            br.Goto(0);

            // Read JMP's Entries
            Entries = new List <JEntry>();
            for (int i = 0; i < entryCount; i++)
            {
                br.Goto(EntryOffset + (i * EntrySize));
                Entries.Add(new JEntry(br, Fields));
            }
        }
Esempio n. 7
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);
        }
Esempio n. 8
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)
                    }
                }
            }
        }
Esempio n. 9
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);
            }
        }
Esempio n. 10
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));
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Read a single material from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public BinMaterial(DhBinaryReader br)
        {
            // Read Index.
            Index = br.ReadS16();

            // Read Unknown 1. (Unused index?)
            Unknown1 = br.ReadS16();

            // Read U-Wrapping.
            WrapU = br.Read();

            // Read V-Wrapping.
            WrapV = br.Read();

            // Read Unknown 2. (Flags?)
            Unknown2 = br.ReadS16();

            // Define a array to hold the unknown 3 values.
            Unknown3 = new int[3];

            // Loop through the unknown 3 values.
            for (int i = 0; i < Unknown3.Length; i++)
            {
                // Write the current unknown value.
                Unknown3[i] = br.ReadS32();
            }
        }
Esempio n. 12
0
        public static byte[] DecodeData(DhBinaryReader br, ushort width, ushort height, TextureFormat format)
        {
            switch (format)
            {
            case TextureFormat.I4:
                return(ReadI4(br, width, height));

            case TextureFormat.I8:
                return(ReadI8(br, width, height));

            case TextureFormat.IA4:
                return(ReadIA4(br, width, height));

            case TextureFormat.IA8:
                return(ReadIA8(br, width, height));

            case TextureFormat.RGB5A3:
                return(ReadRGB5A3(br, width, height));

            case TextureFormat.RGB565:
                return(ReadRGB565(br, width, height));

            case TextureFormat.RGBA32:
                return(ReadRGBA32(br, width, height));

            case TextureFormat.CMPR:
                return(ReadCMPR(br, width, height));

            default:
                throw new NotImplementedException(string.Format("[BTI] {0} is not a supported texture format!", format));
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Read a single primitive vertex from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public BinPrimitiveVertex(DhBinaryReader br, byte useNBT, int uvCount, BinBatchAttributes attributes)
        {
            // Read Matrix Index.
            MatrixIndex = br.ReadS16();

            // Check position attribute.
            if (attributes.HasFlag(BinBatchAttributes.Position))
            {
                // Read Position Index.
                PositionIndex = br.ReadS16();
            }

            // Check normal attribute.
            if (attributes.HasFlag(BinBatchAttributes.Normal))
            {
                // Read Normal Index.
                NormalIndex = br.ReadS16();

                // Check UseNBT flag.
                if (useNBT == 1)
                {
                    // Read BiNormal Index.
                    BiNormalIndex = br.ReadS16();

                    // Read Tangent Index.
                    TangentIndex = br.ReadS16();
                }
            }

            // Define ColorIndex array to hold ColorIndex values.
            ColorIndex = new short[2];

            // Check color2 attribute.
            if (attributes.HasFlag(BinBatchAttributes.Color0))
            {
                // Read the Color1 value.
                ColorIndex[0] = br.ReadS16();
            }

            // Check color1 attribute.
            if (attributes.HasFlag(BinBatchAttributes.Color1))
            {
                // Read the Color1 value.
                ColorIndex[1] = br.ReadS16();
            }

            // Define UVIndex array to hold UVIndex values.
            UVIndex = new short[8];

            // Loop through texCoords.
            for (int i = 0; i < uvCount; i++)
            {
                // Check texCoordX attribute.
                if (attributes.HasFlag((BinBatchAttributes)(1 << (13 + i))))
                {
                    // Read the current UVIndex value.
                    UVIndex[i] = br.ReadS16();
                }
            }
        }
Esempio n. 14
0
        public MDLDrawElement(DhBinaryReader br, List <MDLMaterial> materials, List <MDLShape> shapes)
        {
            MaterialIndex = br.ReadS16();
            ShapeIndex    = br.ReadS16();

            Material = materials[MaterialIndex];
            Shape    = shapes[ShapeIndex];
        }
Esempio n. 15
0
        /// <summary>
        /// Read a single grid index from MP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public GridIndex(DhBinaryReader br)
        {
            // Read TotalTriangleGroupIndex.
            TotalTriangleGroupIndex = br.ReadS32();

            // Read FloorTriangleGroupIndex.
            FloorTriangleGroupIndex = br.ReadS32();
        }
Esempio n. 16
0
        public BinGraphObjectPart(DhBinaryReader br)
        {
            // Read shader index.
            ShaderIndex = br.ReadS16();

            // Read batch index.
            BatchIndex = br.ReadS16();
        }
Esempio n. 17
0
        /// <summary>
        /// Read a single texture coordinate from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public BinTextureCoordinate(DhBinaryReader br)
        {
            // Read X-Coordinate.
            X = br.ReadF32();

            // Read Y-Coordinate.
            Y = br.ReadF32();
        }
Esempio n. 18
0
        /// <summary>
        /// Read a SpritePoint from GEB.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        public SpritePoint(DhBinaryReader br)
        {
            // Read SpritePoint's Position.
            Position = new Vector2(br.ReadF32(), br.ReadF32());

            // Read SpritePoint's Unknown 1.
            Unknown1 = br.ReadS32();
        }
Esempio n. 19
0
        /// <summary>
        /// Read a single keyframe from TMB.
        /// </summary>
        /// <param name="br">The binary reader to read with.</param>
        /// <param name="dataCount">The amount of floats in this keyframe.</param>
        public TIMKeyFrame(DhBinaryReader br, ushort dataCount)
        {
            // Read time.
            Time = br.ReadF32();

            // Read keyframe data.
            Data = br.ReadF32s(dataCount - 1).ToList();
        }
Esempio n. 20
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);
 }
Esempio n. 21
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();
 }
Esempio n. 22
0
        /// <summary>
        /// Method for reading I4 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[] ReadI4(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 < (width / 8); y++)
            {
                // Loop through blocks x.
                for (int x = 0; x < (height / 8); x++)
                {
                    // Loop through pixels in block y.
                    for (int yx = 0; yx < 8; yx++)
                    {
                        // Loop through pixels in block x.
                        for (int xy = 0; xy < 8; xy += 2)
                        {
                            // Determine if pixel is oob (x || y).
                            if ((y * 8 + yx >= height) || (x * 8 + xy >= width))
                            {
                                // Skip.
                                continue;
                            }

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

                            // Calculate RGBA data.
                            byte r1 = (byte)(((pixel & 0xF0) >> 4) * 0x11);
                            byte g1 = (byte)(((pixel & 0xF0) >> 4) * 0x11);
                            byte b1 = (byte)(((pixel & 0xF0) >> 4) * 0x11);
                            byte a1 = 0xFF;
                            byte r2 = (byte)((pixel & 0x0F) * 0x11);
                            byte g2 = (byte)((pixel & 0x0F) * 0x11);
                            byte b2 = (byte)((pixel & 0x0F) * 0x11);
                            byte a2 = 0xFF;

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

                            // Store decoded data in buffer.
                            decoded[offset + 0] = r1;
                            decoded[offset + 1] = g1;
                            decoded[offset + 2] = b1;
                            decoded[offset + 3] = a1;
                            decoded[offset + 4] = r2;
                            decoded[offset + 5] = g2;
                            decoded[offset + 6] = b2;
                            decoded[offset + 7] = a2;
                        }
                    }
                }
            }

            // Return the texture as RGBA.
            return(decoded);
        }
Esempio n. 23
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);
        }
Esempio n. 24
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);
 }
Esempio n. 25
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);
 }
Esempio n. 26
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);
 }
Esempio n. 27
0
        /// <summary>
        /// Method for converting the BTI into a Bitmap.
        /// </summary>
        /// <returns>The BTI as a Bitmap.</returns>
        public Bitmap ToBitmap()
        {
            DhBinaryReader br = new DhBinaryReader(Data, DhEndian.Big);

            byte[]     data    = BTIUtils.DecodeData(br, Width, Height, Format);
            Bitmap     bmp     = new Bitmap(Width, Height);
            Rectangle  rect    = new Rectangle(0, 0, Width, Height);
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            IntPtr     ptr     = bmpData.Scan0;

            Marshal.Copy(data, 0, ptr, data.Length);
            bmp.UnlockBits(bmpData);
            return(bmp);
        }
Esempio n. 28
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));
     }
 }
Esempio n. 29
0
        /// <summary>
        /// Method for reading IA4 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 byte[] containing RGBA data.</returns>
        private static byte[] ReadIA4(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 / 8); 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 < 8; xy++)
                        {
                            // Determine if pixel is oob (x || y).
                            if ((x * 8 + xy >= width) || (y * 4 + yx >= height))
                            {
                                // Skip.
                                continue;
                            }

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

                            // Calculate alpha and luminosity values.
                            byte alpha      = (byte)(((value & 0xF0) >> 4) * 0x11);
                            byte luminosity = (byte)((value & 0x0F) * 0x11);

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

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

            // Return the texture as RGBA.
            return(decoded);
        }
Esempio n. 30
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);
        }