예제 #1
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, object graphics, ushort[] palette, BinaryFileReader r, SittingTransformation sitting)
        {
            _animationIndex = uniqueAnimationIndex;
            int xCenter = r.ReadInt16();
            int yCenter = r.ReadInt16();
            int width   = r.ReadUInt16();
            int height  = r.ReadUInt16();

            // Fix for animations with no pixels.
            if (width == 0 || height == 0)
            {
                Texture = null;
                return;
            }
            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width   += 8;
                height  += 4;
            }
            var data = new byte[width * height * 4];

            // for sitting:
            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.
            fixed(byte *pData = data)
            {
                ushort *dataRef  = (ushort *)pData;
                var     dataRead = 0;
                int     header;

                while ((header = r.ReadInt32()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    var x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    var y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        var       iy         = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                r.Position += header & 0xFFF;
                                continue;
                            }
                            x -= (iy - skew_end) / 2;
                            y -= (iy - skew_end) / 4;
                        }
                    }
                    ushort *cur         = dataRef + y * width + x;
                    ushort *end         = cur + (header & 0xFFF);
                    var     filecounter = 0;
                    var     filedata    = r.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Vector2Int(xCenter, yCenter);
            Texture = new Texture2DInfo(width, height, TextureFormat.BGRA32, false, data);
            _picking.Set(_animationIndex, width, height, data);
        }
예제 #2
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, GraphicsDevice graphics, ushort[] palette, BinaryFileReader reader, SittingTransformation sitting)
        {
            m_AnimationIndex = uniqueAnimationIndex;
            int xCenter = reader.ReadShort();
            int yCenter = reader.ReadShort();
            int width   = reader.ReadUShort();
            int height  = reader.ReadUShort();

            // Fix for animations with no pixels.
            if ((width == 0) || (height == 0))
            {
                Texture = null;
                return;
            }
            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width   += 8;
                height  += 4;
            }
            ushort[] data = new ushort[width * height];
            // for sitting:
            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.
            fixed(ushort *pData = data)
            {
                ushort *dataRef = pData;

                int dataRead = 0;

                int header;

                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    int x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    int y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        int       iy         = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                reader.Position += (header & 0xFFF);
                                continue;
                            }
                            x -= (iy - skew_end) / 2;
                            y -= (iy - skew_end) / 4;
                        }
                    }
                    ushort *cur         = dataRef + y * width + x;
                    ushort *end         = cur + (header & 0xFFF);
                    int     filecounter = 0;
                    byte[]  filedata    = reader.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Point(xCenter, yCenter);
            Texture = new Texture2D(graphics, width, height, false, SurfaceFormat.Bgra5551);
            Texture.SetData(data);
            m_Picking.Set(m_AnimationIndex, width, height, data);
        }
예제 #3
0
        public unsafe AnimationFrame(GraphicsDevice graphics, ushort[] palette, BinaryFileReader reader, SittingTransformation sitting)
        {
            int xCenter = reader.ReadShort();
            int yCenter = reader.ReadShort();

            int width = reader.ReadUShort();
            int height = reader.ReadUShort();

            // Fix for animations with no pixels.
            if ((width == 0) || (height == 0))
            {
                Texture = null;
                return;
            }

            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width += 8;
                height += 4;
            }

            ushort[] data = new ushort[width * height];
            /*for (int i = 0; i < data.Length; i++)
                data[i] = 0xFFFF;*/

            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.

            fixed (ushort* pData = data)
            {
                ushort* dataRef = pData;

                int dataRead = 0;

                int header;
                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;

                    int x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    int y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;

                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end = skew_start - 16;
                        int iy = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                reader.Position += (header & 0xFFF);
                                continue;
                            }
                            else
                            {
                                x -= (iy - skew_end) / 2;
                                y -= (iy - skew_end) / 4;
                            }
                        }
                    }

                    ushort* cur = dataRef + y * width + x;
                    ushort* end = cur + (header & 0xFFF);

                    int filecounter = 0;
                    byte[] filedata = reader.ReadBytes(header & 0xFFF);

                    while (cur < end)
                        *cur++ = palette[filedata[filecounter++]];

                    dataRead += header & 0xFFF;
                }

                Metrics.ReportDataRead(dataRead);
            }

            Center = new Point(xCenter, yCenter);

            Texture = new Texture2D(graphics, width, height, false, SurfaceFormat.Bgra5551);
            Texture.SetData<ushort>(data);
        }