public DrawGroupSprite(ushort type, uint flags, PixelOffset spriteOffset, WorldOffset objectOffset, SpriteFrame frame)
        {
            m_Type = type;
            m_Flags = flags;
            m_SpriteOffset = spriteOffset;
            m_ObjectOffset = objectOffset;
            m_Sprite = frame;

            m_Bitmap = (Bitmap)frame.BitmapData.BitMap.Clone();
            if ((m_Flags & 0x1) == 0x1)
            {
                m_Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
            }
        }
Esempio n. 2
0
        private SpriteFrame ReadFrame(int Index)
        {
            MemoryStream MemStream = new MemoryStream(m_ChunkData);
            BinaryReader Reader    = new BinaryReader(MemStream);

            Reader.BaseStream.Position = m_OffsetTable[Index];

            SpriteFrame Frame = new SpriteFrame();

            if (!m_IsBigEndian)
            {
                Reader.ReadBytes(4); //Reserved.

                Frame.Height    = Reader.ReadUInt16();
                Frame.Width     = Reader.ReadUInt16();
                Frame.PaletteID = (ushort)m_PaletteID;
            }
            else
            {
                Reader.ReadBytes(4); //Reserved.

                Frame.Height    = Endian.SwapUInt16(Reader.ReadUInt16());
                Frame.Width     = Endian.SwapUInt16(Reader.ReadUInt16());
                Frame.PaletteID = (ushort)m_PaletteID;
            }

            Frame.Init(true, false); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

            DecompressFrame2(ref Frame, ref Reader);
            Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

            //Store the frame to avoid having to decompress in the future.
            m_Frames.Add(Frame);

            return(Frame);
        }
        public DrawGroupSprite(ushort type, uint flags, PixelOffset spriteOffset, WorldOffset objectOffset, SpriteFrame frame)
        {
            m_Type         = type;
            m_Flags        = flags;
            m_SpriteOffset = spriteOffset;
            m_ObjectOffset = objectOffset;
            m_Sprite       = frame;

            m_Bitmap = (Bitmap)frame.BitmapData.BitMap.Clone();
            if ((m_Flags & 0x1) == 0x1)
            {
                m_Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
            }
        }
        public SpriteParser(byte[] ChunkData, List <PaletteMap> PMaps, int ChunkID)
        {
            m_ChunkID = ChunkID;

            MemoryStream MemStream = new MemoryStream(ChunkData);
            BinaryReader Reader    = new BinaryReader(MemStream);

            Reader.BaseStream.Position = INDEX_SPRID;
            m_ID = Reader.ReadByte();

            Reader.BaseStream.Position = INDEX_SPRVERSION;
            m_Version = Reader.ReadUInt32();

            if (m_Version != 1000 && m_Version != 1001)
            {
                throw new Exception("Version was: " + m_Version);
            }

            m_FrameCount = Reader.ReadUInt32();

            if (m_Version == 1000)
            {
                m_PaletteID = Reader.ReadUInt32();
            }

            bool PaletteFound = false;

            foreach (PaletteMap Map in PMaps)
            {
                if (Map.ID == m_PaletteID)
                {
                    m_PMap       = Map;
                    PaletteFound = true;
                }
            }

            //This is guesswork, but when the PaletteID is 1, it seems to typically indicate
            //that there's only one palette to choose from...
            if (m_PaletteID == 1)
            {
                m_PMap       = PMaps[0];
                PaletteFound = true;
            }

            if (!PaletteFound)
            {
                throw new Exception("No palette found!");
            }

            for (int i = 0; i < m_FrameCount; i++)
            {
                SpriteFrame Frame = new SpriteFrame();

                Reader.BaseStream.Position = INDEX_SPROFFSETTABLE + 4 * i;
                Reader.BaseStream.Position = Reader.ReadUInt32() + INDEX_SPRVERSION;

                Frame.Width  = Reader.ReadUInt16();
                Frame.Height = Reader.ReadUInt16();
                Frame.Flag   = Reader.ReadUInt16();

                //Zero value skipped.
                Reader.BaseStream.Position += 2;

                Frame.PaletteID = Reader.ReadUInt16();
                Frame.PalMap    = PMaps[0];

                foreach (PaletteMap PMap in PMaps)
                {
                    if (PMap.ID == m_PaletteID)
                    {
                        Frame.PalMap = PMap;
                    }
                }

                Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                Frame.XLocation        = Reader.ReadUInt16();
                Frame.YLocation        = Reader.ReadUInt16();
                Frame.Init();

                EncryptedRowHeader RowHeader = new EncryptedRowHeader();
                int RowID = 0;

                for (int j = 0; j < Frame.Height; j++)
                {
                    long InitPos = Reader.BaseStream.Position;

                    RowHeader = GetDecryptedValues(Reader.ReadUInt16());

                    if (RowHeader.Code == 0)
                    {
                        //byte[] RowSegmentData = Reader.ReadBytes(RowHeader.Count - 2);
                        ReadRowSegment(Reader, RowID, ref Frame);
                        Reader.BaseStream.Position = InitPos + RowHeader.Count;
                        RowID++;
                    }
                    else if (RowHeader.Code == 4)
                    {
                        RowID += RowHeader.Count;
                    }
                    else if (RowHeader.Code == 5)
                    {
                        break;
                    }
                }

                m_Frames.Add(Frame);
            }

            Reader.Close();
        }
        private void ReadRowSegment(BinaryReader SpriteFrameReader, int RowID, ref SpriteFrame Frame, int XPos)
        {
            /*MemoryStream MemStream = new MemoryStream(RowSegmentData);
             * BinaryReader SpriteFrameReader = new BinaryReader(MemStream);*/

            byte Count      = SpriteFrameReader.ReadByte();
            byte FormatCode = (byte)(SpriteFrameReader.ReadByte() / 32);
            int  LastXPos   = 0;
            int  Z          = 0;

            if (FormatCode == 1)
            {
                for (int i = 0; i < Count; i++)
                {
                    Z = SpriteFrameReader.ReadByte();
                    //TODO: Z-level...
                    //int Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    Color Clr   = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    int   Alpha = SpriteFrameReader.ReadByte() /** 8*/;

                    //No idea if this is going to work...

                    /*Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb((0xFF << 16 | 0xFF << 8 | 0xFF),
                     *  Color.FromArgb((0xFF << 24 | Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte())))));*/
                    if (XPos + i < Frame.Width)
                    {
                        Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb(Alpha,
                                                                                  Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte())));
                    }
                }

                LastXPos = XPos + Count;
            }
            else if (FormatCode == 2)
            {
                for (int i = 0; i < Count; i++)
                {
                    Z = SpriteFrameReader.ReadByte();
                    //TODO: Z-level...
                    //int Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    Color Clr   = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    int   Alpha = SpriteFrameReader.ReadByte() /** 8*/;

                    if (i == Frame.Width)
                    {
                        break;
                    }

                    //No idea if this is going to work...

                    /*Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb((Alpha << 16 | Alpha << 8 | Alpha),
                     *  Color.FromArgb((Alpha << 24 | Clr))));*/
                    if (XPos + i < Frame.Width)
                    {
                        Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb(Alpha, Clr));
                    }
                }

                LastXPos = XPos + Count;
                SpriteFrameReader.BaseStream.Position = (Count % 2 == 1) ? 1 : 0;
            }
            else if (FormatCode == 3)
            {
                LastXPos = XPos + Count;
            }
            else if (FormatCode == 5)
            {
                return;
            }
            else if (FormatCode == 6)
            {
                for (int i = 0; i < Count; i++)
                {
                    /*Frame.BitmapData.SetPixel(XPos + i, RowID,
                     *  Color.FromArgb((0xFF << 24 | Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte()))));*/
                    if (XPos + i < Frame.Width)
                    {
                        Frame.BitmapData.SetPixel(XPos + i, RowID,
                                                  Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte()));
                    }
                }

                SpriteFrameReader.BaseStream.Position = SpriteFrameReader.BaseStream.Position = (Count % 2 == 1) ? 1 : 0;
            }

            //if ((SpriteFrameReader.BaseStream.Length - SpriteFrameReader.BaseStream.Position) > 0)
            //{

            /*byte[] RestBytes = SpriteFrameReader.ReadBytes((int)(SpriteFrameReader.BaseStream.Length -
             *  SpriteFrameReader.BaseStream.Position));
             * ReadRowSegment(RestBytes, RowID, ref Frame);*/
            //ReadRowSegment(SpriteFrameReader, RowID, ref Frame, LastXPos);
            //}

            //SpriteFrameReader.Close();
        }
        public SPR2Parser(IffChunk Chunk, List<PaletteMap> PMaps)
            : base(Chunk)
        {
            m_Name = Name;

            int[] offsets;
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_Version = Reader.ReadUInt32();

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version == 1000)
                m_ChunkData = Chunk.Data;

            if (m_Version == 1001)
            {
                m_PaletteID = Reader.ReadUInt32();
                m_FrameCount = Reader.ReadUInt32();
            }
            else
            {
                m_FrameCount = Reader.ReadUInt32();
                m_PaletteID = Reader.ReadUInt32();
            }

            if (PMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PMaps[0]; }
            else
                m_PMap = PMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });

            //Some SPR2s blatantly specify the wrong ID because there's only one palettemap...
            if (m_PMap == null)
            {
                m_PMap = PMaps[0];
            }

            offsets = new int[m_FrameCount];

            if (m_Version == 1000)
            {
                for (int i = 0; i < m_FrameCount; i++)
                {
                    offsets[i] = Reader.ReadInt32();
                    m_FrameOffsets.Add(offsets[i]);
                }
            }

            if (m_Version == 1001)
            {
                for (int l = 0; l < m_FrameCount; l++)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size = Reader.ReadUInt32();
                    Frame.Width = Reader.ReadUInt16();
                    Frame.Height = Reader.ReadUInt16();
                    Frame.Flag = Reader.ReadUInt32();
                    Frame.PaletteID = Reader.ReadUInt16();
                    Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                    Frame.YLocation = Reader.ReadUInt16();
                    Frame.XLocation = Reader.ReadUInt16();

                    if ((SPR2Flags)Frame.Flag == SPR2Flags.HasAlphaChannel)
                        Frame.Init(true, true);
                    else
                    {
                        if ((SPR2Flags)Frame.Flag == SPR2Flags.HasZBufferChannel)
                            Frame.Init(false, true);
                        else
                            Frame.Init(false, false);
                    }

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    if (Frame.HasZBuffer)
                        Frame.ZBuffer.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);
                }
            }

            Reader.Close();
        }
Esempio n. 7
0
        public SpriteParser(byte[] ChunkData, List<PaletteMap> PMaps, int ChunkID)
        {
            m_ChunkID = ChunkID;

            MemoryStream MemStream = new MemoryStream(ChunkData);
            BinaryReader Reader = new BinaryReader(MemStream);

            Reader.BaseStream.Position = INDEX_SPRID;
            m_ID = Reader.ReadByte();

            Reader.BaseStream.Position = INDEX_SPRVERSION;
            m_Version = Reader.ReadUInt32();

            if (m_Version != 1000 && m_Version != 1001)
                throw new Exception("Version was: " + m_Version);

            m_FrameCount = Reader.ReadUInt32();
            
            if (m_Version == 1000)
                m_PaletteID = Reader.ReadUInt32();

            bool PaletteFound = false;

            foreach (PaletteMap Map in PMaps)
            {
                if (Map.ID == m_PaletteID)
                {
                    m_PMap = Map;
                    PaletteFound = true;
                }
            }

            //This is guesswork, but when the PaletteID is 1, it seems to typically indicate
            //that there's only one palette to choose from...
            if (m_PaletteID == 1)
            {
                m_PMap = PMaps[0];
                PaletteFound = true;
            }

            if (!PaletteFound)
                throw new Exception("No palette found!");

            for (int i = 0; i < m_FrameCount; i++)
            {
                SpriteFrame Frame = new SpriteFrame();

                Reader.BaseStream.Position = INDEX_SPROFFSETTABLE + 4 * i;
                Reader.BaseStream.Position = Reader.ReadUInt32() + INDEX_SPRVERSION;

                Frame.Width = Reader.ReadUInt16();
                Frame.Height = Reader.ReadUInt16();
                Frame.Flag = Reader.ReadUInt16();

                //Zero value skipped.
                Reader.BaseStream.Position += 2;

                Frame.PaletteID = Reader.ReadUInt16();
                Frame.PalMap = PMaps[0];

                foreach (PaletteMap PMap in PMaps)
                {
                    if (PMap.ID == m_PaletteID)
                        Frame.PalMap = PMap;
                }

                Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                Frame.XLocation = Reader.ReadUInt16();
                Frame.YLocation = Reader.ReadUInt16();
                Frame.Init();

                EncryptedRowHeader RowHeader = new EncryptedRowHeader();
                int RowID = 0;

                for (int j = 0; j < Frame.Height; j++)
                {
                    long InitPos = Reader.BaseStream.Position;

                    RowHeader = GetDecryptedValues(Reader.ReadUInt16());

                    if (RowHeader.Code == 0)
                    {
                        //byte[] RowSegmentData = Reader.ReadBytes(RowHeader.Count - 2);
                        ReadRowSegment(Reader, RowID, ref Frame);
                        Reader.BaseStream.Position = InitPos + RowHeader.Count;
                        RowID++;
                    }
                    else if (RowHeader.Code == 4)
                    {
                        RowID += RowHeader.Count;
                    }
                    else if (RowHeader.Code == 5)
                    {
                        break;
                    }
                }

                m_Frames.Add(Frame);
            }

            Reader.Close();
        }
Esempio n. 8
0
        private void DecompressFrame2(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            bool  quit = false;
            byte  Clr  = 0;
            Color Transparent;
            int   CurrentRow = 0, CurrentColumn = 0;

            byte PixCommand, PixCount = 0;

            if (m_PMap == null)
            {
                m_PMap = new PaletteMap();
            }

            while (quit == false)
            {
                byte RowCommand = Reader.ReadByte();
                byte RowCount   = Reader.ReadByte();

                switch (RowCommand)
                {
                case 0x00:     //Start marker; the count byte is ignored.
                    break;

                //Fill this row with pixel data that directly follows; the count byte of the row command denotes the
                //size in bytes of the row and pixel data.
                case 0x04:
                    RowCount     -= 2;
                    CurrentColumn = 0;

                    while (RowCount > 0)
                    {
                        PixCommand = Reader.ReadByte();
                        PixCount   = Reader.ReadByte();
                        RowCount  -= 2;

                        switch (PixCommand)
                        {
                        case 1:         //Leave the next pixel count pixels as transparent.
                            Transparent = Color.FromArgb(0, 0, 0, 0);
                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);
                            }

                            CurrentColumn += PixCount;

                            break;

                        case 2:         //Fill the next pixel count pixels with a palette color.
                            //The pixel data is two bytes: the first byte denotes the palette color index, and the
                            //second byte is padding (which is always equal to the first byte but is ignored).
                            Clr = Reader.ReadByte();
                            Reader.ReadByte();         //Padding
                            RowCount -= 2;

                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow),
                                                          m_PMap.GetColorAtIndex(Clr));
                            }

                            CurrentColumn += PixCount;

                            break;

                        case 3:         //Set the next pixel count pixels to the palette color indices defined by the
                            //pixel data provided directly after this command.

                            byte Padding = (byte)(PixCount % 2);

                            if (Padding != 0)
                            {
                                RowCount -= (byte)(PixCount + Padding);
                            }
                            else
                            {
                                RowCount -= PixCount;
                            }

                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Clr = Reader.ReadByte();
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow),
                                                          m_PMap.GetColorAtIndex(Clr));
                            }

                            CurrentColumn += PixCount;

                            if (Padding != 0)
                            {
                                Reader.ReadByte();
                            }

                            break;
                        }
                    }

                    CurrentRow++;

                    break;

                case 0x05:     //End marker. The count byte is always 0, but may be ignored.

                    //Some sprites don't have these, so read them using ReadBytes(), which
                    //simply returns an empty array if the stream couldn't be read.
                    Reader.ReadBytes(2);     //PixCommand and PixCount.

                    quit = true;
                    break;

                case 0x09:     //Leave the next count rows as transparent.
                    PixCommand = Reader.ReadByte();
                    PixCount   = Reader.ReadByte();

                    Transparent = Color.FromArgb(0, 0, 0, 0);

                    for (int i = 0; i < RowCount; i++)
                    {
                        for (int j = CurrentColumn; j < Frame.Width; j++)
                        {
                            Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);
                        }

                        CurrentRow++;
                    }

                    break;

                case 0x10:     //Start marker, equivalent to 0x00; the count byte is ignored.
                    break;
                }

                if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                {
                    break;
                }
            }
        }
Esempio n. 9
0
        private SpriteFrame ReadFrame(int Index)
        {
            MemoryStream MemStream = new MemoryStream(m_ChunkData);
            BinaryReader Reader = new BinaryReader(MemStream);

            Reader.BaseStream.Position = m_OffsetTable[Index];

            SpriteFrame Frame = new SpriteFrame();

            if (!m_IsBigEndian)
            {
                Reader.ReadBytes(4); //Reserved.

                Frame.Height = Reader.ReadUInt16();
                Frame.Width = Reader.ReadUInt16();
                Frame.PaletteID = (ushort)m_PaletteID;
            }
            else
            {
                Reader.ReadBytes(4); //Reserved.

                Frame.Height = Endian.SwapUInt16(Reader.ReadUInt16());
                Frame.Width = Endian.SwapUInt16(Reader.ReadUInt16());
                Frame.PaletteID = (ushort)m_PaletteID;
            }

            Frame.Init(true); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

            DecompressFrame2(ref Frame, ref Reader);
            Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

            //Store the frame to avoid having to decompress in the future.
            m_Frames.Add(Frame);

            return Frame;
        }
Esempio n. 10
0
        /// <summary>
        /// The DGRP chunk is used to combine multiple sprites into one object.
        /// </summary>
        /// <param name="ChunkData">The data for the chunk.</param>
        /// <param name="Sprites">The sprites that the DGRP consists of.</param>
        public DrawGroup(IffChunk Chunk, List <SPR2Parser> Sprites) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_ID      = ID;
            m_Sprites = Sprites;

            //Reader.BaseStream.Position = INDEX_VERSION;
            m_Version = Reader.ReadUInt16() - 20000;

            uint Count = (m_Version < 3) ? Reader.ReadUInt16() : Reader.ReadUInt32();
            uint SpriteCount, DirectionFlag, Zoom;

            for (int i = 0; i < Count; i++)
            {
                if (m_Version < 3)
                {
                    SpriteCount   = Reader.ReadUInt16();
                    DirectionFlag = Reader.ReadByte();
                    Zoom          = Reader.ReadByte();
                }
                else
                {
                    DirectionFlag = Reader.ReadUInt32();
                    Zoom          = Reader.ReadUInt32();
                    SpriteCount   = Reader.ReadUInt32();
                }
                DrawGroupImg Image = new DrawGroupImg(SpriteCount, DirectionFlag, Zoom);

                for (int j = 0; j < SpriteCount; j++)
                {
                    ushort Tag = 0;
                    int    PixelX = 0, PixelY = 0;
                    uint   SprID = 0, SprFrameID = 0, Flags = 0;
                    float  ZOffset = 0, XOffset = 0, YOffset = 0;

                    if (m_Version < 3)
                    {
                        Tag        = Reader.ReadUInt16();
                        SprID      = Reader.ReadUInt16();
                        SprFrameID = Reader.ReadUInt16();
                        Flags      = Reader.ReadUInt16();
                        PixelX     = Reader.ReadInt16();
                        PixelY     = Reader.ReadInt16();

                        if (m_Version == 1)
                        {
                            ZOffset = Reader.ReadUInt32();
                        }
                    }
                    else
                    {
                        SprID      = Reader.ReadUInt32();
                        SprFrameID = Reader.ReadUInt32();
                        PixelX     = Reader.ReadInt32();
                        PixelY     = Reader.ReadInt32();
                        ZOffset    = Reader.ReadUInt32();
                        Flags      = Reader.ReadUInt32();
                        if (m_Version == 4)
                        {
                            XOffset = Reader.ReadUInt32();
                            YOffset = Reader.ReadUInt32();
                        }
                    }

                    SpriteFrame Frame = FindSpriteFrame(SprID, SprFrameID);
                    if (Frame != null)
                    {
                        DrawGroupSprite Sprite = new DrawGroupSprite(Tag, Flags, new PixelOffset(PixelX, PixelY),
                                                                     new WorldOffset(XOffset, YOffset, ZOffset), Frame);
                        Image.Sprites.Insert(0, Sprite);
                    }
                }

                //Image.CompileSprites();
                m_Images.Add(Image);
            }
        }
        private void DecompressFrame2(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            bool  Quit = false;
            int   CurrentRow = 0, CurrentColumn = 0;
            int   Padding = 0;
            Color Clr, ZClr; //The current color and the current color for the z-buffer.

            while (Quit == false)
            {
                int[] RowHeader = GetDecryptedValues(Reader.ReadUInt16());
                switch (RowHeader[0])
                {
                case 0:            //Fill this row with pixel data that directly follows; the count byte of the row
                                   //command denotes the size in bytes of the row's command/count bytes together
                                   //with the supplied pixel data.
                    int RowCount = RowHeader[1];
                    RowCount -= 2; //Row command + count bytes.

                    while (RowCount > 0)
                    {
                        int[] PixelHeader = GetDecryptedValues(Reader.ReadUInt16());
                        RowCount -= 2;

                        int PixelCount = PixelHeader[1];

                        switch (PixelHeader[0])
                        {
                        case 1:         //Set the next pixel count pixels in the z-buffer and color sprites to the
                                        //values defined by the pixel data provided directly after this command.
                            RowCount -= PixelCount * 2;

                            while (PixelCount > 0)
                            {
                                Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                       Color.FromArgb(Reader.ReadByte(), 0, 0, 0));

                                Clr = m_PMap.GetColorAtIndex(Reader.ReadByte());
                                if (Clr != Frame.TransparentPixel)
                                {
                                    Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                }
                                else
                                {
                                    Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                              Color.FromArgb(0, 0, 0, 0));
                                }

                                PixelCount--;
                                CurrentColumn++;
                            }

                            break;

                        case 2:         //Set the next pixel count pixels in the z-buffer, color, and alpha
                                        //sprites to the values defined by the pixel data provided directly after
                                        //this command.
                            Padding   = PixelCount % 2;
                            RowCount -= (PixelCount * 3) + Padding;

                            while (PixelCount > 0)
                            {
                                ZClr = Color.FromArgb(Reader.ReadByte());
                                Clr  = m_PMap.GetColorAtIndex(Reader.ReadByte());

                                //Read the alpha.
                                Clr  = Color.FromArgb(Reader.ReadByte(), Clr);
                                ZClr = Color.FromArgb(Clr.A, ZClr);

                                Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow), ZClr);

                                PixelCount--;
                                CurrentColumn++;
                            }

                            if (Padding != 0)
                            {
                                Reader.ReadByte();
                            }

                            break;

                        case 3:         //Leave the next pixel count pixels in the color sprite filled with the
                                        //transparent color, in the z-buffer sprite filled with 255, and in the
                                        //alpha sprite filled with 0. This pixel command has no pixel data.
                            while (PixelCount > 0)
                            {
                                //This is completely transparent regardless of whether the frame
                                //supports alpha.
                                Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                          Color.FromArgb(0, 0, 0, 0));

                                if (Frame.HasZBuffer)
                                {
                                    Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                           Color.FromArgb(255, 255, 255, 255));
                                }

                                PixelCount--;
                                CurrentColumn++;
                            }

                            break;

                        case 6:         //Set the next pixel count pixels in the color sprite to the palette color
                                        //indices defined by the pixel data provided directly after this command.
                            Padding   = PixelCount % 2;
                            RowCount -= PixelCount + Padding;

                            while (PixelCount > 0)
                            {
                                Clr = m_PMap.GetColorAtIndex(Reader.ReadByte());
                                if (Clr != Frame.TransparentPixel)
                                {
                                    Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                }
                                else
                                {
                                    Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                              Color.FromArgb(0, 0, 0, 0));
                                }

                                if (Frame.HasZBuffer)
                                {
                                    if (Clr != Frame.TransparentPixel)
                                    {
                                        Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                               Color.FromArgb(255, 1, 1, 1));
                                    }
                                    else
                                    {
                                        Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                                  Color.FromArgb(255, 255, 255, 255));
                                    }
                                }

                                PixelCount--;
                                CurrentColumn++;
                            }

                            if (Padding != 0)
                            {
                                Reader.ReadByte();
                            }

                            break;
                        }

                        if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                        {
                            break;
                        }
                    }

                    CurrentRow++;
                    CurrentColumn = 0;

                    break;

                case 4:     //Leave the next count rows in the color sprite filled with the transparent color,
                            //in the z-buffer sprite filled with 255, and in the alpha sprite filled with 0.
                    for (int i = 0; i < RowHeader[1]; i++)
                    {
                        for (int j = 0; j < Frame.Width; j++)
                        {
                            Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                      Color.FromArgb(0, 0, 0, 0));

                            if (Frame.HasZBuffer)
                            {
                                Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                       Color.FromArgb(255, 255, 255, 255));
                            }

                            CurrentColumn++;
                        }

                        CurrentColumn = 0;
                        CurrentRow++;
                    }

                    CurrentColumn = 0;

                    break;

                case 5:     //Sprite end marker; the count byte is always 0, but may be ignored.
                    Quit = true;
                    break;
                }

                if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                {
                    break;
                }
            }
        }
        private void DecompressFrame(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            int  row                 = 0;
            int  column              = 0;
            bool quit                = false;
            int  lastType            = 0;
            int  numCodesTillNewline = 0;

            try
            {
                while (quit == false)
                {
                    int[] rowHeader = GetDecryptedValues(Reader.ReadUInt16());
                    switch (rowHeader[0])
                    {
                    case 0:
                        column = 0;
                        numCodesTillNewline = rowHeader[1];
                        for (int bytesRead = 0; bytesRead < numCodesTillNewline - 2; bytesRead += 2)
                        {
                            int[] rowHeader2 = GetDecryptedValues(Reader.ReadUInt16());
                            try
                            {
                                switch (rowHeader2[0])
                                {
                                case 1:
                                    for (int i = 0; i < rowHeader2[1]; i++)
                                    {
                                        int Z = Reader.ReadByte();

                                        byte b = Reader.ReadByte();
                                        Frame.BitmapData.SetPixel(new Point(column++, row), m_PMap.GetColorAtIndex(b));
                                        bytesRead += 2;
                                    }
                                    break;

                                case 2:
                                    for (int i = 0; i < rowHeader2[1]; i++)
                                    {
                                        int Z = Reader.ReadByte();

                                        byte  b   = Reader.ReadByte();
                                        Color clr = m_PMap.GetColorAtIndex(b);
                                        Frame.BitmapData.SetPixel(new Point(column++, row), Color.FromArgb(Reader.ReadByte(), clr));
                                        bytesRead += 3;
                                    }
                                    if (Reader.BaseStream.Position % 2 == 1)
                                    {
                                        Reader.ReadByte(); bytesRead++;
                                    }
                                    break;

                                case 3:
                                    column += rowHeader2[1];
                                    break;

                                case 6:
                                    for (int i = 0; i < rowHeader2[1]; i++)
                                    {
                                        byte b = Reader.ReadByte();
                                        Frame.BitmapData.SetPixel(new Point(column++, row), m_PMap.GetColorAtIndex(b));
                                        bytesRead++;
                                    }
                                    if (Reader.BaseStream.Position % 2 == 1)
                                    {
                                        Reader.ReadByte(); bytesRead++;
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception e)
                            {
                                Log.LogThis(String.Format("Error reading code {0} ({1}). Last code read was {2}.",
                                                          rowHeader2[0], e.Message, lastType), eloglevel.error);
                            }
                            lastType = rowHeader2[0];
                        }
                        row++;
                        break;

                    case 4:
                        for (int i = 0; i < rowHeader[1]; i++)
                        {
                            row++;
                            column = 0;
                        }
                        break;

                    case 5:
                        quit = true;
                        break;

                    default:
                        Log.LogThis("Error reading code " + lastType + '!', eloglevel.error);
                        break;
                    }
                    if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                    {
                        break;
                    }
                    lastType = rowHeader[0];
                }
            }
            catch (Exception E)
            {
                Log.LogThis("Unable to parse SPR2! \r\n" + "Version: " + m_Version + "\r\n" + "PaletteID: " + m_PaletteID +
                            "\r\n" + "FrameCount: " + m_FrameCount + "\r\n" + E.ToString() + "\r\n", eloglevel.error);
            }
        }
        public SPR2Parser(IffChunk Chunk, List <PaletteMap> PMaps) : base(Chunk)
        {
            m_Name = Name;

            int[]        offsets;
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_Version = Reader.ReadUInt32();

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version == 1000)
            {
                m_ChunkData = Chunk.Data;
            }

            if (m_Version == 1001)
            {
                m_PaletteID  = Reader.ReadUInt32();
                m_FrameCount = Reader.ReadUInt32();
            }
            else
            {
                m_FrameCount = Reader.ReadUInt32();
                m_PaletteID  = Reader.ReadUInt32();
            }

            if (PMaps.Count == 1 && m_PaletteID == 1)
            {
                m_PMap = PMaps[0];
            }
            else
            {
                m_PMap = PMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                {
                                                                    return(true);
                                                                }
                                                                return(false); });
            }

            //Some SPR2s blatantly specify the wrong ID because there's only one palettemap...
            if (m_PMap == null)
            {
                m_PMap = PMaps[0];
            }

            offsets = new int[m_FrameCount];

            if (m_Version == 1000)
            {
                for (int i = 0; i < m_FrameCount; i++)
                {
                    offsets[i] = Reader.ReadInt32();
                    m_FrameOffsets.Add(offsets[i]);
                }
            }

            if (m_Version == 1001)
            {
                for (int l = 0; l < m_FrameCount; l++)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version          = Reader.ReadUInt32();
                    Frame.Size             = Reader.ReadUInt32();
                    Frame.Width            = Reader.ReadUInt16();
                    Frame.Height           = Reader.ReadUInt16();
                    Frame.Flag             = Reader.ReadUInt32();
                    Frame.PaletteID        = Reader.ReadUInt16();
                    Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                    Frame.YLocation        = Reader.ReadUInt16();
                    Frame.XLocation        = Reader.ReadUInt16();

                    if ((SPR2Flags)Frame.Flag == SPR2Flags.HasAlphaChannel)
                    {
                        Frame.Init(true, true);
                    }
                    else
                    {
                        if ((SPR2Flags)Frame.Flag == SPR2Flags.HasZBufferChannel)
                        {
                            Frame.Init(false, true);
                        }
                        else
                        {
                            Frame.Init(false, false);
                        }
                    }

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    if (Frame.HasZBuffer)
                    {
                        Frame.ZBuffer.Unlock(true); //The bitmapdata is locked when the frame is created.
                    }
                    m_Frames.Add(Frame);
                }
            }

            Reader.Close();
        }
Esempio n. 14
0
        public DrawGroup(byte[] ChunkData, List <SpriteParser> Sprites)
        {
            MemoryStream MemStream = new MemoryStream(ChunkData);
            BinaryReader Reader    = new BinaryReader(MemStream);

            Reader.BaseStream.Position = INDEX_VERSION;
            m_Version = Reader.ReadUInt16() - 20000;

            uint         Count = (m_Version < 3) ? Reader.ReadUInt16() : Reader.ReadUInt32();
            uint         SpriteCount;
            DrawGroupImg Img;

            for (int i = 0; i < Count; i++)
            {
                if (m_Version < 3)
                {
                    SpriteCount = Reader.ReadUInt16();
                    ushort DirectionFlag = Reader.ReadUInt16();
                    ushort Zoom          = Reader.ReadUInt16();

                    Img            = new DrawGroupImg(DirectionFlag, Zoom);
                    Img.BitmapData = new Bitmap(136, 184);
                }
                else
                {
                    uint DirectionFlag = Reader.ReadUInt32();
                    uint Zoom          = Reader.ReadUInt32();
                    SpriteCount = Reader.ReadUInt32();

                    m_Img            = new DrawGroupImg(DirectionFlag, Zoom);
                    m_Img.BitmapData = new Bitmap(136, 384);
                }

                for (int j = 0; j < SpriteCount; j++)
                {
                    uint Tag, SprID, SprFrameID, Flags, PixelX, PixelY, ZOffset, XOffset, YOffset;

                    if (m_Version < 3)
                    {
                        SprID      = Reader.ReadUInt16();
                        Tag        = Reader.ReadUInt16();
                        SprFrameID = Reader.ReadUInt16();
                        Flags      = Reader.ReadUInt16();
                        PixelX     = Reader.ReadUInt16();
                        PixelY     = Reader.ReadUInt16();

                        if (m_Version == 1)
                        {
                            ZOffset = Reader.ReadUInt16();
                        }
                    }
                    else
                    {
                        SprID = Reader.ReadUInt32();
                        Reader.BaseStream.Position = +3;
                        SprFrameID = Reader.ReadUInt32();
                        PixelX     = Reader.ReadUInt32();
                        PixelY     = Reader.ReadUInt32();
                        ZOffset    = Reader.ReadUInt32();
                        Flags      = Reader.ReadUInt32();
                        XOffset    = Reader.ReadUInt32();
                        YOffset    = Reader.ReadUInt32();
                    }

                    foreach (SpriteParser Sprite in Sprites)
                    {
                        if (Sprite.ID == SprID)
                        {
                            SpriteFrame Frame = Sprite.GetFrame((int)SprFrameID);

                            if (Frame != null)
                            {
                                RectangleF Rect = new RectangleF(Frame.XLocation, Frame.YLocation, Frame.Width, Frame.Height);
                                m_Img.BitmapData.Clone(Rect, Frame.BitmapData.PixelFormat);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        private void DecompressFrame2(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            bool quit = false;
            byte Clr = 0;
            Color Transparent;
            int CurrentRow = 0, CurrentColumn = 0;

            byte PixCommand, PixCount = 0;

            while (quit == false)
            {
                byte RowCommand = Reader.ReadByte();
                byte RowCount = Reader.ReadByte();

                switch (RowCommand)
                {
                    case 0x00: //Start marker; the count byte is ignored.
                        break;
                    //Fill this row with pixel data that directly follows; the count byte of the row command denotes the
                    //size in bytes of the row and pixel data.
                    case 0x04:
                        RowCount -= 2;
                        CurrentColumn = 0;

                        while (RowCount > 0)
                        {
                            PixCommand = Reader.ReadByte();
                            PixCount = Reader.ReadByte();
                            RowCount -= 2;

                            switch (PixCommand)
                            {
                                case 1: //Leave the next pixel count pixels as transparent.
                                    Transparent = Color.FromArgb(0, 0, 0, 0);
                                    for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                                    {
                                        Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);

                                        /*if (j == Frame.Width)
                                            CurrentRow++;*/
                                    }

                                    CurrentColumn += PixCount;

                                    break;
                                case 2: //Fill the next pixel count pixels with a palette color.
                                    //The pixel data is two bytes: the first byte denotes the palette color index, and the
                                    //second byte is padding (which is always equal to the first byte but is ignored).
                                    Clr = Reader.ReadByte();
                                    Reader.ReadByte(); //Padding
                                    RowCount -= 2;

                                    for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                                    {
                                        Frame.BitmapData.SetPixel(new Point(j, CurrentRow), m_PMap.GetColorAtIndex(Clr));

                                        /*if (j == Frame.Width)
                                            CurrentRow++;*/
                                    }

                                    CurrentColumn += PixCount;

                                    break;
                                case 3: //Set the next pixel count pixels to the palette color indices defined by the
                                    //pixel data provided directly after this command.

                                    byte Padding = (byte)(PixCount % 2);

                                    if (Padding != 0)
                                        RowCount -= (byte)(PixCount + Padding);
                                    else
                                        RowCount -= PixCount;

                                    for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                                    {
                                        Clr = Reader.ReadByte();
                                        Frame.BitmapData.SetPixel(new Point(j, CurrentRow), m_PMap.GetColorAtIndex(Clr));

                                        /*if (j == (Frame.Width - 1))
                                            CurrentRow++;*/
                                    }

                                    CurrentColumn += PixCount;

                                    if (Padding != 0)
                                        Reader.ReadByte();

                                    break;
                            }
                        }

                        CurrentRow++;

                        break;
                    case 0x05: //End marker. The count byte is always 0, but may be ignored.

                        //Some sprites don't have these, so read them using ReadBytes(), which
                        //simply returns an empty array if the stream couldn't be read.
                        Reader.ReadBytes(2); //PixCommand and PixCount.

                        quit = true;
                        break;
                    case 0x09: //Leave the next count rows as transparent.
                        PixCommand = Reader.ReadByte();
                        PixCount = Reader.ReadByte();

                        Transparent = Color.FromArgb(0, 0, 0, 0);

                        for (int i = 0; i < RowCount; i++)
                        {
                            for (int j = CurrentColumn; j < Frame.Width; j++)
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);

                            CurrentRow++;
                        }

                        break;
                    case 0x10: //Start marker, equivalent to 0x00; the count byte is ignored.
                        break;
                }

                if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                    break;
            }
        }
Esempio n. 16
0
        public SPRParser(IffChunk Chunk, List<PaletteMap> PaletteMaps)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            //The two first bytes aren't used by the version...
            ushort FirstBytes = Reader.ReadUInt16();

            if (FirstBytes == 0)
            {
                m_IsBigEndian = true;
                m_Version = (uint)Endian.SwapUInt16(Reader.ReadUInt16());
            }
            else
            {
                m_Version = (uint)FirstBytes;
                Reader.ReadUInt16();
            }

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version != 1001)
                m_ChunkData = Chunk.Data;

            if (m_IsBigEndian)
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID = Endian.SwapUInt32(Reader.ReadUInt32());

                    for (uint i = 0; i < m_FrameCount; i++)
                        m_OffsetTable.Add(Endian.SwapUInt32(Reader.ReadUInt32()));

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
                else
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID = Endian.SwapUInt32(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
            }
            else
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID = Reader.ReadUInt32();

                    for (uint i = 0; i < m_FrameCount; i++)
                        m_OffsetTable.Add(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
                else
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID = Reader.ReadUInt32();

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
            }

            if (m_Version == 1001)
            {
                //Framecount may be set to -1 and should be ignored...
                while(true)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size = Reader.ReadUInt32();

                    Reader.ReadBytes(4); //Reserved.

                    Frame.Height = Reader.ReadUInt16();
                    Frame.Width = Reader.ReadUInt16();
                    Frame.Init(true); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);

                    if ((Reader.BaseStream.Position == Reader.BaseStream.Length) ||
                        (Reader.BaseStream.Position - Reader.BaseStream.Length < 14))
                        break;
                }
            }

            Reader.Close();
        }
        public SpriteFrame ReadFrame(int Index)
        {
            BinaryReader Reader = new BinaryReader(new MemoryStream(m_ChunkData));
            Reader.BaseStream.Seek(m_FrameOffsets[Index], SeekOrigin.Begin);

            SpriteFrame Frame = new SpriteFrame();

            Frame.FrameIndex = (uint)Index;
            Frame.Width = Reader.ReadUInt16();
            Frame.Height = Reader.ReadUInt16();
            Frame.Flag = Reader.ReadUInt32();
            Frame.PaletteID = Reader.ReadUInt16();
            Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
            Frame.YLocation = Reader.ReadUInt16();
            Frame.XLocation = Reader.ReadUInt16();

            if (Frame.Flag == 0x07)
                Frame.Init(true, true);
            else
            {
                if ((SPR2Flags)Frame.Flag == SPR2Flags.HasZBufferChannel)
                    Frame.Init(false, true);
                else
                    Frame.Init(false, false);
            }

            DecompressFrame2(ref Frame, ref Reader);
            Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

            if (Frame.HasZBuffer)
                Frame.ZBuffer.Unlock(true); //The bitmapdata is locked when the frame is created.

            Reader.Close();

            //Store the frame to avoid having to decompress in the future.
            m_Frames.Add(Frame);

            return Frame;
        }
        private void DecompressFrame(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            int row = 0;
            int column = 0;
            bool quit = false;
            int lastType = 0;
            int numCodesTillNewline = 0;

            try
            {
                while (quit == false)
                {
                    int[] rowHeader = GetDecryptedValues(Reader.ReadUInt16());
                    switch (rowHeader[0])
                    {
                        case 0:
                            column = 0;
                            numCodesTillNewline = rowHeader[1];
                            for (int bytesRead = 0; bytesRead < numCodesTillNewline - 2; bytesRead += 2)
                            {
                                int[] rowHeader2 = GetDecryptedValues(Reader.ReadUInt16());
                                try
                                {
                                    switch (rowHeader2[0])
                                    {
                                        case 1:
                                            for (int i = 0; i < rowHeader2[1]; i++)
                                            {
                                                int Z = Reader.ReadByte();

                                                byte b = Reader.ReadByte();
                                                Frame.BitmapData.SetPixel(new Point(column++, row), m_PMap.GetColorAtIndex(b));
                                                bytesRead += 2;
                                            }
                                            break;
                                        case 2:
                                            for (int i = 0; i < rowHeader2[1]; i++)
                                            {
                                                int Z = Reader.ReadByte();

                                                byte b = Reader.ReadByte();
                                                Color clr = m_PMap.GetColorAtIndex(b);
                                                Frame.BitmapData.SetPixel(new Point(column++, row), Color.FromArgb(Reader.ReadByte(), clr));
                                                bytesRead += 3;
                                            }
                                            if (Reader.BaseStream.Position % 2 == 1) { Reader.ReadByte(); bytesRead++; }
                                            break;
                                        case 3:
                                            column += rowHeader2[1];
                                            break;
                                        case 6:
                                            for (int i = 0; i < rowHeader2[1]; i++)
                                            {
                                                byte b = Reader.ReadByte();
                                                Frame.BitmapData.SetPixel(new Point(column++, row), m_PMap.GetColorAtIndex(b));
                                                bytesRead++;
                                            }
                                            if (Reader.BaseStream.Position % 2 == 1) { Reader.ReadByte(); bytesRead++; }
                                            break;
                                        default:
                                            break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    Log.LogThis(String.Format("Error reading code {0} ({1}). Last code read was {2}.",
                                        rowHeader2[0], e.Message, lastType), eloglevel.error);
                                }
                                lastType = rowHeader2[0];
                            }
                            row++;
                            break;
                        case 4:
                            for (int i = 0; i < rowHeader[1]; i++)
                            {
                                row++;
                                column = 0;
                            }
                            break;
                        case 5:
                            quit = true;
                            break;
                        default:
                            Log.LogThis("Error reading code " + lastType + '!', eloglevel.error);
                            break;
                    }
                    if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                        break;
                    lastType = rowHeader[0];
                }
            }
            catch (Exception E)
            {
                Log.LogThis("Unable to parse SPR2! \r\n" + "Version: " + m_Version + "\r\n" + "PaletteID: " + m_PaletteID +
                    "\r\n" + "FrameCount: " + m_FrameCount + "\r\n" + E.ToString() + "\r\n", eloglevel.error);
            }
        }
        private void DecompressFrame2(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            bool Quit = false;
            int CurrentRow = 0, CurrentColumn = 0;
            int Padding = 0;
            Color Clr, ZClr; //The current color and the current color for the z-buffer.

            while (Quit == false)
            {
                int[] RowHeader = GetDecryptedValues(Reader.ReadUInt16());
                switch (RowHeader[0])
                {
                    case 0: //Fill this row with pixel data that directly follows; the count byte of the row
                            //command denotes the size in bytes of the row's command/count bytes together
                            //with the supplied pixel data.
                        int RowCount = RowHeader[1];
                        RowCount -= 2; //Row command + count bytes.

                        while (RowCount > 0)
                        {
                            int[] PixelHeader = GetDecryptedValues(Reader.ReadUInt16());
                            RowCount -= 2;

                            int PixelCount = PixelHeader[1];

                            switch (PixelHeader[0])
                            {
                                case 1: //Set the next pixel count pixels in the z-buffer and color sprites to the
                                        //values defined by the pixel data provided directly after this command.
                                    RowCount -= PixelCount * 2;

                                    while (PixelCount > 0)
                                    {
                                        Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                            Color.FromArgb(Reader.ReadByte(), 0, 0, 0));

                                        Clr = m_PMap.GetColorAtIndex(Reader.ReadByte());
                                        if (Clr != Frame.TransparentPixel)
                                            Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                        else
                                            Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                Color.FromArgb(0, 0, 0, 0));

                                        PixelCount--;
                                        CurrentColumn++;
                                    }

                                    break;
                                case 2: //Set the next pixel count pixels in the z-buffer, color, and alpha
                                        //sprites to the values defined by the pixel data provided directly after
                                        //this command.
                                    Padding = PixelCount % 2;
                                    RowCount -= (PixelCount * 3) + Padding;

                                    while (PixelCount > 0)
                                    {
                                        ZClr = Color.FromArgb(Reader.ReadByte());
                                        Clr = m_PMap.GetColorAtIndex(Reader.ReadByte());

                                        //Read the alpha.
                                        Clr = Color.FromArgb(Reader.ReadByte(), Clr);
                                        ZClr = Color.FromArgb(Clr.A, ZClr);

                                        Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                        Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow), ZClr);

                                        PixelCount--;
                                        CurrentColumn++;
                                    }

                                    if (Padding != 0)
                                        Reader.ReadByte();

                                    break;
                                case 3: //Leave the next pixel count pixels in the color sprite filled with the
                                        //transparent color, in the z-buffer sprite filled with 255, and in the
                                        //alpha sprite filled with 0. This pixel command has no pixel data.
                                    while (PixelCount > 0)
                                    {
                                        //This is completely transparent regardless of whether the frame
                                        //supports alpha.
                                        Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                            Color.FromArgb(0, 0, 0, 0));

                                        if(Frame.HasZBuffer)
                                            Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                Color.FromArgb(255, 255, 255, 255));

                                        PixelCount--;
                                        CurrentColumn++;
                                    }

                                    break;
                                case 6: //Set the next pixel count pixels in the color sprite to the palette color
                                        //indices defined by the pixel data provided directly after this command.
                                    Padding = PixelCount % 2;
                                    RowCount -= PixelCount + Padding;

                                    while (PixelCount > 0)
                                    {
                                        Clr = m_PMap.GetColorAtIndex(Reader.ReadByte());
                                        if (Clr != Frame.TransparentPixel)
                                            Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow), Clr);
                                        else
                                            Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                Color.FromArgb(0, 0, 0, 0));

                                        if (Frame.HasZBuffer)
                                        {
                                            if (Clr != Frame.TransparentPixel)
                                                Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                    Color.FromArgb(255, 1, 1, 1));
                                            else
                                                Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                                    Color.FromArgb(255, 255, 255, 255));
                                        }

                                        PixelCount--;
                                        CurrentColumn++;
                                    }

                                    if (Padding != 0)
                                        Reader.ReadByte();

                                    break;
                            }

                            if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                                break;
                        }

                        CurrentRow++;
                        CurrentColumn = 0;

                        break;
                    case 4: //Leave the next count rows in the color sprite filled with the transparent color,
                            //in the z-buffer sprite filled with 255, and in the alpha sprite filled with 0.
                        for (int i = 0; i < RowHeader[1]; i++)
                        {
                            for (int j = 0; j < Frame.Width; j++)
                            {
                                Frame.BitmapData.SetPixel(new Point(CurrentColumn, CurrentRow),
                                    Color.FromArgb(0, 0, 0, 0));

                                if (Frame.HasZBuffer)
                                {
                                    Frame.ZBuffer.SetPixel(new Point(CurrentColumn, CurrentRow),
                                        Color.FromArgb(255, 255, 255, 255));
                                }

                                CurrentColumn++;
                            }

                            CurrentColumn = 0;
                            CurrentRow++;
                        }

                        CurrentColumn = 0;

                        break;
                    case 5: //Sprite end marker; the count byte is always 0, but may be ignored.
                        Quit = true;
                        break;
                }

                if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                    break;
            }
        }
Esempio n. 20
0
        public SPRParser(IffChunk Chunk, List <PaletteMap> PaletteMaps) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            //The two first bytes aren't used by the version...
            ushort FirstBytes = Reader.ReadUInt16();

            if (FirstBytes == 0)
            {
                m_IsBigEndian = true;
                m_Version     = (uint)Endian.SwapUInt16(Reader.ReadUInt16());
            }
            else
            {
                m_Version = (uint)FirstBytes;
                Reader.ReadUInt16();
            }

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version != 1001)
            {
                m_ChunkData = Chunk.Data;
            }

            if (m_IsBigEndian)
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID  = Endian.SwapUInt32(Reader.ReadUInt32());

                    for (uint i = 0; i < m_FrameCount; i++)
                    {
                        m_OffsetTable.Add(Endian.SwapUInt32(Reader.ReadUInt32()));
                    }

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
                else
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID  = Endian.SwapUInt32(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
            }
            else
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID  = Reader.ReadUInt32();

                    for (uint i = 0; i < m_FrameCount; i++)
                    {
                        m_OffsetTable.Add(Reader.ReadUInt32());
                    }

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
                else
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID  = Reader.ReadUInt32();

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
            }

            if (m_Version == 1001)
            {
                //Framecount may be set to -1 and should be ignored...
                while (true)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size    = Reader.ReadUInt32();

                    Reader.ReadBytes(4); //Reserved.

                    Frame.Height = Reader.ReadUInt16();
                    Frame.Width  = Reader.ReadUInt16();
                    Frame.Init(true, false); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);

                    if ((Reader.BaseStream.Position == Reader.BaseStream.Length) ||
                        (Reader.BaseStream.Position - Reader.BaseStream.Length < 14))
                    {
                        break;
                    }
                }
            }

            Reader.Close();
        }
Esempio n. 21
0
        private void ReadRowSegment(BinaryReader SpriteFrameReader, int RowID, ref SpriteFrame Frame, int XPos)
        {
            /*MemoryStream MemStream = new MemoryStream(RowSegmentData);
            BinaryReader SpriteFrameReader = new BinaryReader(MemStream);*/

            byte Count = SpriteFrameReader.ReadByte();
            byte FormatCode = (byte)(SpriteFrameReader.ReadByte() / 32);
            int LastXPos = 0;
            int Z = 0;

            if (FormatCode == 1)
            {
                for (int i = 0; i < Count; i++)
                {
                    Z = SpriteFrameReader.ReadByte();
                    //TODO: Z-level...
                    //int Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    Color Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    int Alpha = SpriteFrameReader.ReadByte() /** 8*/;

                    //No idea if this is going to work...
                    /*Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb((0xFF << 16 | 0xFF << 8 | 0xFF),
                        Color.FromArgb((0xFF << 24 | Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte())))));*/
                    if (XPos + i < Frame.Width)
                    {
                        Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb(Alpha,
                            Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte())));
                    }
                }

                LastXPos = XPos + Count;
            }
            else if (FormatCode == 2)
            {
                for (int i = 0; i < Count; i++)
                {
                    Z = SpriteFrameReader.ReadByte();
                    //TODO: Z-level...
                    //int Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    Color Clr = Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte());
                    int Alpha = SpriteFrameReader.ReadByte() /** 8*/;

                    if (i == Frame.Width)
                        break;

                    //No idea if this is going to work...
                    /*Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb((Alpha << 16 | Alpha << 8 | Alpha),
                        Color.FromArgb((Alpha << 24 | Clr))));*/
                    if(XPos + i < Frame.Width)
                        Frame.BitmapData.SetPixel(XPos + i, RowID, Color.FromArgb(Alpha, Clr));
                }

                LastXPos = XPos + Count;
                SpriteFrameReader.BaseStream.Position = (Count % 2 == 1) ? 1 : 0;
            }
            else if (FormatCode == 3)
            {
                LastXPos = XPos + Count;
            }
            else if (FormatCode == 5)
            {
                return;
            }
            else if (FormatCode == 6)
            {
                for (int i = 0; i < Count; i++)
                {
                    /*Frame.BitmapData.SetPixel(XPos + i, RowID,
                        Color.FromArgb((0xFF << 24 | Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte()))));*/
                    if (XPos + i < Frame.Width)
                    {
                        Frame.BitmapData.SetPixel(XPos + i, RowID,
                            Frame.PalMap.GetColorAtIndex(SpriteFrameReader.ReadByte()));
                    }
                }

                SpriteFrameReader.BaseStream.Position = SpriteFrameReader.BaseStream.Position = (Count % 2 == 1) ? 1 : 0;
            }

            //if ((SpriteFrameReader.BaseStream.Length - SpriteFrameReader.BaseStream.Position) > 0)
            //{
                /*byte[] RestBytes = SpriteFrameReader.ReadBytes((int)(SpriteFrameReader.BaseStream.Length -
                    SpriteFrameReader.BaseStream.Position));
                ReadRowSegment(RestBytes, RowID, ref Frame);*/
                //ReadRowSegment(SpriteFrameReader, RowID, ref Frame, LastXPos);
            //}

            //SpriteFrameReader.Close();
        }