The frame (I.E sprite) of a SPR2 chunk.
Inheritance: ITextureProvider, IWorldTextureProvider
コード例 #1
0
        public static System.Drawing.Color[] QuantizeFrame(SPR2Frame frame, out byte[] bytes)
        {
            var bmps = frame.GetPixelAlpha(frame.Width, frame.Height, new Vector2());

            /*
             * SimplePaletteQuantizer.Quantizers.IColorQuantizer quantizer = new DistinctSelectionQuantizer();
             *
             * using (ImageBuffer buffer = new ImageBuffer(bmps[0], ImageLockMode.ReadOnly))
             * {
             *  quantizer.Prepare(buffer);
             *  buffer.ScanColors(quantizer, 4); // 4 = parallel task count
             * }
             *
             * Bitmap quantpx = new Bitmap(bmps[0].Width, bmps[0].Height, PixelFormat.Format8bppIndexed);
             * ImageBuffer.DitherImage(bmps[0], quantpx, new JarvisJudiceNinkeDitherer(), quantizer, 255, 4);*/

            var quantpx = (Bitmap)ImageBuffer.QuantizeImage(bmps[0], new DistinctSelectionQuantizer(), null, 255, 4);
            var palt    = quantpx.Palette.Entries;

            var data = quantpx.LockBits(new System.Drawing.Rectangle(0, 0, quantpx.Width, quantpx.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

            bytes = new byte[data.Height * data.Width];

            // copy the bytes from bitmap to array
            for (int i = 0; i < data.Height; i++)
            {
                Marshal.Copy(data.Scan0 + i * data.Stride, bytes, i * data.Width, data.Width);
            }

            return(palt);
        }
コード例 #2
0
ファイル: SPR2.cs プロジェクト: Bengrs/FreeSO
        /// <summary>
        /// Reads a SPR2 chunk from a stream.
        /// </summary>
        /// <param name="iff">An Iff instance.</param>
        /// <param name="stream">A Stream object holding a SPR2 chunk.</param>
        public override void Read(IffFile iff, Stream stream)
        {
            using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN))
            {
                var  version     = io.ReadUInt32();
                uint spriteCount = 0;

                if (version == 1000)
                {
                    spriteCount      = io.ReadUInt32();
                    DefaultPaletteID = io.ReadUInt32();
                    var offsetTable = new uint[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        offsetTable[i] = io.ReadUInt32();
                    }

                    Frames = new SPR2Frame[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        var frame = new SPR2Frame(this);
                        io.Seek(SeekOrigin.Begin, offsetTable[i]);

                        var guessedSize = ((i + 1 < offsetTable.Length) ? offsetTable[i + 1] : (uint)stream.Length) - offsetTable[i];

                        frame.Read(version, io, guessedSize);
                        Frames[i] = frame;
                    }
                }
                else if (version == 1001)
                {
                    DefaultPaletteID = io.ReadUInt32();
                    spriteCount      = io.ReadUInt32();

                    Frames = new SPR2Frame[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        var frame = new SPR2Frame(this);
                        frame.Read(version, io, 0);
                        Frames[i] = frame;
                    }
                }
            }
        }
コード例 #3
0
ファイル: SPR2.cs プロジェクト: RHY3756547/FreeSO
        /// <summary>
        /// Reads a SPR2 chunk from a stream.
        /// </summary>
        /// <param name="iff">An Iff instance.</param>
        /// <param name="stream">A Stream object holding a SPR2 chunk.</param>
        public override void Read(IffFile iff, Stream stream)
        {
            using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN))
            {
                var version = io.ReadUInt32();
                uint spriteCount = 0;

                if (version == 1000)
                {
                    spriteCount = io.ReadUInt32();
                    DefaultPaletteID = io.ReadUInt32();
                    var offsetTable = new uint[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        offsetTable[i] = io.ReadUInt32();
                    }

                    Frames = new SPR2Frame[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        var frame = new SPR2Frame(this);
                        io.Seek(SeekOrigin.Begin, offsetTable[i]);

                        var guessedSize = ((i + 1 < offsetTable.Length) ? offsetTable[i + 1] : (uint)stream.Length) - offsetTable[i];

                        frame.Read(version, io, guessedSize);
                        Frames[i] = frame;
                    }
                }
                else if (version == 1001)
                {
                    DefaultPaletteID = io.ReadUInt32();
                    spriteCount = io.ReadUInt32();

                    Frames = new SPR2Frame[spriteCount];
                    for (var i = 0; i < spriteCount; i++)
                    {
                        var frame = new SPR2Frame(this);
                        frame.Read(version, io, 0);
                        Frames[i] = frame;
                    }
                }
            }
        }
コード例 #4
0
        private void NewRotation(int num)
        {
            Content.Content.Get().Changes.BlockingResMod(new ResAction(() =>
            {
                var oldToNew = new Dictionary<int, int>();

                var old = GraphicChunk.Frames;
                var oldLen = old.Length;
                var result = new SPR2Frame[oldLen+num*3];
                var index = 0;

                for (int j = 0; j < 3; j++) {
                    for (int i = 0; i < oldLen / 3; i++)
                    {
                        oldToNew.Add(j * (oldLen / 3) + i, index);
                        result[index++] = old[j * (oldLen / 3) + i];
                    }
                    for (int i=0; i<num; i++)
                        result[index++] = new SPR2Frame(GraphicChunk) { PaletteID = (ushort)GraphicChunk.DefaultPaletteID };
                }
                GraphicChunk.Frames = result;

                foreach (var dgrp in GraphicChunk.ChunkParent.List<DGRP>())
                {
                    foreach (var img in dgrp.Images)
                    {
                        foreach (var spr in img.Sprites)
                        {
                            if (spr.SpriteID == GraphicChunk.ChunkID)
                            {
                                var oldspr = spr.SpriteFrameIndex;
                                if (oldToNew.ContainsKey((int)spr.SpriteFrameIndex))
                                    spr.SpriteFrameIndex = (uint)oldToNew[(int)spr.SpriteFrameIndex];
                                else
                                    spr.SpriteFrameIndex = 0;
                                if (oldspr != spr.SpriteFrameIndex) Content.Content.Get().Changes.ChunkChanged(dgrp);
                            }
                        }
                    }
                }

            }, GraphicChunk));
            SetActiveResource(GraphicChunk, ActiveIff);
            FrameList.SelectedIndex = FrameList.Items.Count - 1;
        }
コード例 #5
0
        public static void WriteFrame(SPR2Frame frame, IoWriter output)
        {
            var bytes = frame.PalData;
            var col   = frame.PixelData;
            var zs    = frame.ZBufferData;

            int index      = 0;
            int blankLines = 0;

            for (int y = 0; y < frame.Height; y++)
            {
                byte        lastCmd  = 0;
                List <byte> dataBuf  = new List <byte>();
                int         rlecount = 0;
                bool        anySolid = false;

                var scanStream = new MemoryStream();
                var scanOut    = IoWriter.FromStream(scanStream, ByteOrder.LITTLE_ENDIAN);

                for (int x = 0; x < frame.Width; x++)
                {
                    byte plt = bytes[index];
                    byte a   = col[index].A;
                    byte z   = zs[index];

                    var cmd = getCmd(plt, a, z);

                    if (x == 0 || cmd != lastCmd)
                    {
                        if (x != 0)
                        {
                            //write a command to write the last sequence of pixels
                            scanOut.WriteUInt16((ushort)(((int)lastCmd << 13) | rlecount));
                            if ((dataBuf.Count % 2) != 0)
                            {
                                dataBuf.Add(0);
                            }
                            scanOut.WriteBytes(dataBuf.ToArray());
                            dataBuf.Clear();
                        }

                        lastCmd  = cmd;
                        rlecount = 0;
                    }

                    switch (cmd)
                    {
                    case 0x1:
                    case 0x2:
                        dataBuf.Add(z);
                        dataBuf.Add(plt);
                        if (cmd == 0x2)
                        {
                            dataBuf.Add((byte)Math.Ceiling(a / 8.2258064516129032258064516129032));
                        }
                        anySolid = true;
                        break;

                    case 0x6:
                        dataBuf.Add(plt);
                        anySolid = true;
                        break;

                    default:
                        break;
                    }
                    rlecount++;

                    index++;
                }

                if (anySolid)
                {
                    //write a command to write the last sequence of pixels
                    scanOut.WriteUInt16((ushort)(((int)lastCmd << 13) | rlecount));
                    if ((dataBuf.Count % 2) != 0)
                    {
                        dataBuf.Add(0);
                    }
                    scanOut.WriteBytes(dataBuf.ToArray());
                    dataBuf.Clear();
                }

                var scanData = scanStream.ToArray();

                if (scanData.Length == 0)
                {
                    blankLines++; //line is transparent
                }
                else
                {
                    if (blankLines > 0)
                    {
                        //add transparent lines before our new command
                        output.WriteUInt16((ushort)((0x4 << 13) | blankLines));
                        blankLines = 0;
                    }
                    output.WriteUInt16((ushort)(scanData.Length + 2));
                    output.WriteBytes(scanData);
                }
            }

            if (blankLines > 0)
            {
                //add transparent lines before our new command
                output.WriteUInt16((ushort)((0x4 << 13) | blankLines));
                blankLines = 0;
            }
            output.WriteUInt16((ushort)(0x5 << 13));

            return;
        }
コード例 #6
0
ファイル: SPR2FrameEncoder.cs プロジェクト: RHY3756547/FreeSO
        public static void WriteFrame(SPR2Frame frame, IoWriter output)
        {
            var bytes = frame.PalData;
            var col = frame.PixelData;
            var zs = frame.ZBufferData;

            int index = 0;
            int blankLines = 0;
            for (int y=0; y<frame.Height; y++)
            {
                byte lastCmd = 0;
                List<byte> dataBuf = new List<byte>();
                int rlecount = 0;
                bool anySolid = false;

                var scanStream = new MemoryStream();
                var scanOut = IoWriter.FromStream(scanStream, ByteOrder.LITTLE_ENDIAN);

                for (int x=0; x<frame.Width; x++)
                {
                    byte plt = bytes[index];
                    byte a = col[index].A;
                    byte z = zs[index];

                    var cmd = getCmd(plt, a, z);

                    if (x == 0 || cmd != lastCmd)
                    {
                        if (x != 0)
                        {
                            //write a command to write the last sequence of pixels
                            scanOut.WriteUInt16((ushort)(((int)lastCmd<<13)|rlecount));
                            if ((dataBuf.Count % 2) != 0) dataBuf.Add(0);
                            scanOut.WriteBytes(dataBuf.ToArray());
                            dataBuf.Clear();
                        }

                        lastCmd = cmd;
                        rlecount = 0;
                    }

                    switch (cmd)
                    {
                        case 0x1:
                        case 0x2:
                            dataBuf.Add(z);
                            dataBuf.Add(plt);
                            if (cmd == 0x2) dataBuf.Add((byte)Math.Ceiling(a/ 8.2258064516129032258064516129032));
                            anySolid = true;
                            break;
                        case 0x6:
                            dataBuf.Add(plt);
                            anySolid = true;
                            break;
                        default:
                            break;
                    }
                    rlecount++;

                    index++;
                }

                if (anySolid)
                {
                    //write a command to write the last sequence of pixels
                    scanOut.WriteUInt16((ushort)(((int)lastCmd << 13) | rlecount));
                    if ((dataBuf.Count % 2) != 0) dataBuf.Add(0);
                    scanOut.WriteBytes(dataBuf.ToArray());
                    dataBuf.Clear();
                }

                var scanData = scanStream.ToArray();

                if (scanData.Length == 0)
                    blankLines++; //line is transparent
                else
                {
                    if (blankLines > 0)
                    {
                        //add transparent lines before our new command
                        output.WriteUInt16((ushort)((0x4<<13) | blankLines));
                        blankLines = 0;
                    }
                    output.WriteUInt16((ushort)(scanData.Length+2));
                    output.WriteBytes(scanData);
                }

            }

            if (blankLines > 0)
            {
                //add transparent lines before our new command
                output.WriteUInt16((ushort)((0x4 << 13) | blankLines));
                blankLines = 0;
            }
            output.WriteUInt16((ushort)(0x5<<13));

            return;
        }
コード例 #7
0
        public static Microsoft.Xna.Framework.Color[] QuantizeFrame(SPR2Frame frame, out byte[] bytes)
        {
            var bmps = GetPixelAlpha(frame, frame.Width, frame.Height, new Vector2());

            var quantpx = (Bitmap)ImageBuffer.QuantizeImage(bmps[0], new DistinctSelectionQuantizer(), null, 255, 4);
            var palt = quantpx.Palette.Entries;

            var data = quantpx.LockBits(new System.Drawing.Rectangle(0, 0, quantpx.Width, quantpx.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            bytes = new byte[data.Height * data.Width];

            // copy the bytes from bitmap to array
            for (int i = 0; i < data.Height; i++)
            {
                Marshal.Copy(data.Scan0 + i * data.Stride, bytes, i * data.Width, data.Width);
            }

            var result = new Microsoft.Xna.Framework.Color[palt.Length];
            for (int i=0; i<palt.Length; i++)
            {
                var c = palt[i];
                result[i] = new Microsoft.Xna.Framework.Color(c.R, c.G, c.B, c.A);
            }
            return result;
        }
コード例 #8
0
        public static System.Drawing.Image[] GetPixelAlpha(SPR2Frame sprite, int tWidth, int tHeight, Vector2 pos)
        {
            var result = new System.Drawing.Bitmap[3];
            var locks = new BitmapData[3];
            var data = new byte[3][];
            for (int i = 0; i < 3; i++)
            {
                result[i] = new System.Drawing.Bitmap(tWidth, tHeight, PixelFormat.Format24bppRgb);
                locks[i] = result[i].LockBits(new System.Drawing.Rectangle(0, 0, tWidth, tHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
                data[i] = new byte[locks[i].Stride * locks[i].Height];
            }

            int index = 0;
            for (int y = 0; y < tHeight; y++)
            {
                for (int x = 0; x < tWidth; x++)
                {
                    Microsoft.Xna.Framework.Color col;
                    byte depth = 255;

                    if (x >= pos.X && x < pos.X + sprite.Width && y >= pos.Y && y < pos.Y + sprite.Height)
                    {
                        col = sprite.PixelData[(int)(x - pos.X) + (int)(y - pos.Y) * sprite.Width];
                        if (col.A == 0) col = new Microsoft.Xna.Framework.Color(0xFF, 0xFF, 0x00, 0x00);
                        if (sprite.ZBufferData != null)
                        {
                            depth = sprite.ZBufferData[(int)(x - pos.X) + (int)(y - pos.Y) * sprite.Width];
                        }
                    }
                    else
                    {
                        col = new Microsoft.Xna.Framework.Color(0xFF, 0xFF, 0x00, 0x00);
                    }

                    data[0][index] = col.B;
                    data[0][index + 1] = col.G;
                    data[0][index + 2] = col.R;
                    data[0][index + 3] = 255;

                    data[1][index] = col.A;
                    data[1][index + 1] = col.A;
                    data[1][index + 2] = col.A;
                    data[1][index + 3] = 255;

                    data[2][index] = depth;
                    data[2][index + 1] = depth;
                    data[2][index + 2] = depth;
                    data[2][index + 3] = 255;

                    index += 4;
                }
            }

            for (int i = 0; i < 3; i++)
            {
                Marshal.Copy(data[i], 0, locks[i].Scan0, data[i].Length);
                result[i].UnlockBits(locks[i]);
            }

            return result;
        }
コード例 #9
0
 /// <summary>
 /// Generates windows bitmaps for the appearance of this sprite.
 /// </summary>
 /// <param name="tWidth"></param>
 /// <param name="tHeight"></param>
 /// <returns>Array of three images, [Color, Alpha, Depth].</returns>
 public static System.Drawing.Image[] GetPixelAlpha(SPR2Frame sprite, int tWidth, int tHeight)
 {
     return GetPixelAlpha(sprite, tWidth, tHeight, sprite.Position);
 }