예제 #1
0
        public object Serdes(object existing, AssetInfo config, AssetMapping mapping, ISerializer s)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            ApiUtil.Assert(config.Transposed != true);

            int width     = s.UInt16(null, 0);
            int height    = s.UInt16(null, 0);
            int something = s.UInt8(null, 0);

            ApiUtil.Assert(something == 0);
            int spriteCount = s.UInt8(null, 0);

            bool uniform    = config.File.Format != "NonUniform";
            var  frames     = new AlbionSpriteFrame[spriteCount];
            var  frameBytes = new List <byte[]>();
            int  currentY   = 0;

            int spriteWidth = 0;

            for (int i = 0; i < spriteCount; i++)
            {
                if (!uniform && i > 0)
                {
                    width     = s.UInt16(null, 0);
                    height    = s.UInt16(null, 0);
                    something = s.UInt8(null, 0);
                    ApiUtil.Assert(something == 0);
                    int spriteCount2 = s.UInt8(null, 0);
                    ApiUtil.Assert(spriteCount2 == spriteCount);
                }

                var bytes = s.ByteArray(null, null, width * height);
                frames[i] = new AlbionSpriteFrame(0, currentY, width, height);
                frameBytes.Add(bytes);

                currentY += height;
                if (width > spriteWidth)
                {
                    spriteWidth = width;
                }
            }

            byte[] pixelData = new byte[spriteCount * spriteWidth * currentY];
            for (int n = 0; n < spriteCount; n++)
            {
                var frame = frames[n];

                for (int j = 0; j < frame.Height; j++)
                {
                    for (int i = 0; i < frame.Width; i++)
                    {
                        pixelData[(frame.Y + j) * spriteWidth + frame.X + i] = frameBytes[n][j * frame.Width + i];
                    }
                }
            }

            s.Check();
            return(new AlbionSprite(config.AssetId.ToString(), spriteWidth, currentY, uniform, pixelData, frames));
        }
예제 #2
0
        public object Serdes(object existing, AssetInfo config, AssetMapping mapping, ISerializer s)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }
            if (s.Mode != SerializerMode.Reading)
            {
                throw new NotImplementedException("Fixed size sprite saving not currently supported");
            }

            var streamLength = s.BytesRemaining;

            if (streamLength == 0)
            {
                return(null);
            }

            int width  = config.EffectiveWidth;
            int height = config.EffectiveHeight;

            if (width == 0)
            {
                width = (int)Math.Sqrt(streamLength);
            }
            if (height == 0)
            {
                height = (int)streamLength / width;
            }

            // ApiUtil.Assert(streamLength % width == 0);
            // ApiUtil.Assert(streamLength % (width * height) == 0);

            // long initialPosition = s.BaseStream.Position;
            int spriteCount = Math.Max(1, unchecked ((int)(streamLength / (width * height))));

            height = (int)streamLength / (width * spriteCount);

            int currentY  = 0;
            var pixelData = new byte[spriteCount * width * height];
            var frames    = new AlbionSpriteFrame[spriteCount];

            for (int n = 0; n < spriteCount; n++)
            {
                frames[n] = new AlbionSpriteFrame(0, currentY, width, height);

                var bytes = s.ByteArray(null, null, width * height);
                for (int i = 0; i < width * height; i++)
                {
                    pixelData[n * width * height + i] = bytes[i];
                }

                currentY += height;
            }

            var sprite = new AlbionSprite(config.AssetId.ToString(), width, height * spriteCount, true, pixelData, frames);

            if (!config.Transposed)
            {
                return(sprite);
            }

            int rotatedFrameHeight = width;

            pixelData = new byte[spriteCount * width * height];
            frames    = new AlbionSpriteFrame[spriteCount];
            for (int n = 0; n < spriteCount; n++)
            {
                frames[n] = new AlbionSpriteFrame(0, rotatedFrameHeight * n, height, rotatedFrameHeight);

                ApiUtil.RotateImage(width, height,
                                    new ReadOnlySpan <byte>(sprite.PixelData, n * width * height, width * height),
                                    new Span <byte>(pixelData, n * width * height, width * height));
            }

            return(new AlbionSprite(config.AssetId.ToString(), height, width * spriteCount, true, pixelData, frames));
        }