예제 #1
0
        private IEnumerable <CfsBitmap> LoadCfsBitmapFromBlob(LoadedBlobFile blob)
        {
            var entries = blob.BlobFile.Entries
                          .Where(e => e.Name.Trim().ToLower().EndsWith(".cfs"))
                          .SelectMany(e =>
            {
                using (var stream = new MemoryStream())
                {
                    blob.Stream.Seek(e.Offset, SeekOrigin.Begin);
                    blob.Stream.CopyTo(stream, (int)e.Size);

                    stream.Seek(0, SeekOrigin.Begin);

                    var spriteFile = new SpriteFile();
                    spriteFile.Deserialize(stream);

                    return(CfsBitmap.FromSpriteFile(spriteFile, blob.BlobName, e.Name));
                }
            }).ToList();

            blob.Stream.Close();
            blob.Stream.Dispose();

            return(entries);
        }
예제 #2
0
        public void TestSaveMethod()
        {
            SpriteFile spriteFile = new SpriteFile();
            spriteFile.Load(TEST_FILE);

            MemoryStream savedStream = new MemoryStream();
            spriteFile.Save(savedStream);

            savedStream.Seek(0, SeekOrigin.Begin);

            SpriteFile savedSpriteFile = new SpriteFile();
            savedSpriteFile.Load(savedStream);

            savedStream.Close();

            Assert.AreEqual(spriteFile.Textures.Count, savedSpriteFile.Textures.Count, "Texture counts do not match");
            Assert.AreEqual(spriteFile.Sprites.Count, savedSpriteFile.Sprites.Count, "Sprite counts do not match");

            for (int i = 0; i < spriteFile.Textures.Count; i++) {
                Assert.AreEqual(spriteFile.Textures[i].FileName, savedSpriteFile.Textures[i].FileName, "Texture file names values do not match");
                Assert.AreEqual(spriteFile.Textures[i].ColourKey, savedSpriteFile.Textures[i].ColourKey, "Texture colour key values do not match");
            }

            for (int i = 0; i < spriteFile.Sprites.Count; i++) {
                Assert.AreEqual(spriteFile.Sprites[i].Texture, savedSpriteFile.Sprites[i].Texture, "Sprite texture values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].X1, savedSpriteFile.Sprites[i].X1, "Sprite X1 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].Y1, savedSpriteFile.Sprites[i].Y1, "Sprite Y1 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].X2, savedSpriteFile.Sprites[i].X2, "Sprite X2 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].Y2, savedSpriteFile.Sprites[i].Y2, "Sprite Y2 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].ID, savedSpriteFile.Sprites[i].ID, "Sprite ID values do not match");
            }
        }
예제 #3
0
 public SpriteModel(string name, uint crc, SpriteFile spriteFile)
     : base(name,
            crc,
            new Vector3(spriteFile.MaximumWidth / -2, spriteFile.MaximumWidth / -2, spriteFile.MaximumHeight / -2),
            new Vector3(spriteFile.MaximumWidth / 2, spriteFile.MaximumWidth / 2, spriteFile.MaximumHeight / 2))
 {
     SpriteFile = spriteFile ?? throw new ArgumentNullException(nameof(spriteFile));
 }
예제 #4
0
 public static void Main(string[] args)
 {
     using (var input = File.OpenRead("AtlasFlying.cfs"))
     {
         var cfs = new SpriteFile();
         cfs.Deserialize(input);
     }
 }
예제 #5
0
        private static void Export(string inputPath, string outputPath)
        {
            var inputBytes = File.ReadAllBytes(inputPath);

            if (BitConverter.ToUInt32(inputBytes, 0) == 0x67687361) // 'ashg'
            {
                inputBytes = RLE.Decompress(inputBytes, 0, inputBytes.Length);
            }

            var file = new SpriteFile();

            using (var input = new MemoryStream(inputBytes, false))
            {
                file.Deserialize(input, Endian.Little);
            }

            var sprite = file.Sprite;

            if (sprite.Texture != null)
            {
                var texture = sprite.Texture.Value;
                if (sprite.Palettes.Length == 1)
                {
                    var bitmapPath = Path.ChangeExtension(outputPath, ".png");
                    var data       = ExportPalettized(texture, sprite.Palettes[0]);
                    var bitmap     = MakeBitmapPalettized(
                        texture.TotalWidth, texture.TotalHeight,
                        data,
                        sprite.Palettes[0]);
                    using (bitmap)
                    {
                        bitmap.Save(bitmapPath, ImageFormat.Png);
                    }
                }
                else
                {
                    int i = 0;
                    foreach (var palette in sprite.Palettes)
                    {
                        var bitmapPath = Path.ChangeExtension($"{outputPath}_{i}", ".png");
                        var data       = ExportPalettized(texture, palette);
                        var bitmap     = MakeBitmapPalettized(
                            texture.TotalWidth, texture.TotalHeight,
                            data,
                            palette);
                        using (bitmap)
                        {
                            bitmap.Save(bitmapPath, ImageFormat.Png);
                        }
                        i++;
                    }
                }
            }
        }
예제 #6
0
    public SpriteItemViewModel(SpriteFile sprite, IOverrideSpriteProvider spriteProvider, IDialogService dialogService, SpriteTypeViewModel parent)
    {
        _parent         = parent;
        _dialogService  = dialogService;
        _spriteProvider = spriteProvider;
        Id           = sprite.Id;
        _spriteType  = sprite.Type;
        _isOverride  = sprite.IsOverride;
        _displayFile = sprite.File;

        RevertCommand      = new RelayCommand(Revert, () => _isOverride);
        ExportCommand      = new RelayCommand(Export);
        SetOverrideCommand = new RelayCommand(SetOverride);

        UpdateDisplayImage();
    }
예제 #7
0
        public void TestLoadMethod()
        {
            const int TEXTURE_COUNT = 38;
            const int SPRITE_COUNT = 648;

            Stream stream = File.OpenRead(TEST_FILE);

            stream.Seek(0, SeekOrigin.End);
            long fileSize = stream.Position;
            stream.Seek(0, SeekOrigin.Begin);

            SpriteFile spriteFile = new SpriteFile();
            spriteFile.Load(stream);

            long streamPosition = stream.Position;
            stream.Close();

            Assert.AreEqual(fileSize, streamPosition, "Not all of the file was read");
            Assert.AreEqual(TEXTURE_COUNT, spriteFile.Textures.Count, "Incorrect texture count");
            Assert.AreEqual(SPRITE_COUNT, spriteFile.Sprites.Count, "Incorrect sprite count");
        }
예제 #8
0
    private void ReloadSprite()
    {
        if (String.IsNullOrEmpty(SpriteFile))
        {
            return;
        }

        if (SpriteFile.EndsWith(".sprite"))
        {
            Sprite = SpriteManager.Create(SpriteFile);
            try {
                Sprite.Action = action;
            } catch (System.Collections.Generic.KeyNotFoundException) {
                Console.WriteLine($"error: action '{action}' not found in '{SpriteFile}'");
            }
        }
        else
        {
            DefaultSpriteFile = SpriteFile;
            Sprite            = SpriteManager.CreateFromImage(DefaultSpriteFile);
        }
    }
예제 #9
0
        public void TestSaveMethod()
        {
            SpriteFile spriteFile = new SpriteFile();

            spriteFile.Load(TEST_FILE);

            MemoryStream savedStream = new MemoryStream();

            spriteFile.Save(savedStream);

            savedStream.Seek(0, SeekOrigin.Begin);

            SpriteFile savedSpriteFile = new SpriteFile();

            savedSpriteFile.Load(savedStream);

            savedStream.Close();

            Assert.AreEqual(spriteFile.Textures.Count, savedSpriteFile.Textures.Count, "Texture counts do not match");
            Assert.AreEqual(spriteFile.Sprites.Count, savedSpriteFile.Sprites.Count, "Sprite counts do not match");

            for (int i = 0; i < spriteFile.Textures.Count; i++)
            {
                Assert.AreEqual(spriteFile.Textures[i].FileName, savedSpriteFile.Textures[i].FileName, "Texture file names values do not match");
                Assert.AreEqual(spriteFile.Textures[i].ColourKey, savedSpriteFile.Textures[i].ColourKey, "Texture colour key values do not match");
            }

            for (int i = 0; i < spriteFile.Sprites.Count; i++)
            {
                Assert.AreEqual(spriteFile.Sprites[i].Texture, savedSpriteFile.Sprites[i].Texture, "Sprite texture values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].X1, savedSpriteFile.Sprites[i].X1, "Sprite X1 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].Y1, savedSpriteFile.Sprites[i].Y1, "Sprite Y1 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].X2, savedSpriteFile.Sprites[i].X2, "Sprite X2 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].Y2, savedSpriteFile.Sprites[i].Y2, "Sprite Y2 values do not match");
                Assert.AreEqual(spriteFile.Sprites[i].ID, savedSpriteFile.Sprites[i].ID, "Sprite ID values do not match");
            }
        }
예제 #10
0
        public void TestLoadMethod()
        {
            const int TEXTURE_COUNT = 38;
            const int SPRITE_COUNT  = 648;

            Stream stream = File.OpenRead(TEST_FILE);

            stream.Seek(0, SeekOrigin.End);
            long fileSize = stream.Position;

            stream.Seek(0, SeekOrigin.Begin);

            SpriteFile spriteFile = new SpriteFile();

            spriteFile.Load(stream);

            long streamPosition = stream.Position;

            stream.Close();

            Assert.AreEqual(fileSize, streamPosition, "Not all of the file was read");
            Assert.AreEqual(TEXTURE_COUNT, spriteFile.Textures.Count, "Incorrect texture count");
            Assert.AreEqual(SPRITE_COUNT, spriteFile.Sprites.Count, "Incorrect sprite count");
        }
예제 #11
0
        public void InitializeWithEntryAndStream(BlobFile.Entry entry, Stream stream)
        {
            var dontFixSpecialColors = true;

            sprite = new SpriteFile();
            sprite.Deserialize(stream);

            lblFileName.Text = entry.Name;

            if (!string.IsNullOrWhiteSpace(sprite.Category))
            {
                lblFileName.Text = $"{entry.Name} ({sprite.Category})";
            }

            pictureBoxPreview.Width  = sprite.Width;
            pictureBoxPreview.Height = sprite.Height;

            bitmap = new Bitmap(sprite.Width, sprite.Height, PixelFormat.Format8bppIndexed);

            var palette     = bitmap.Palette;
            var shadowIndex = 256 - sprite.ShadowCount;
            var lightIndex  = shadowIndex - sprite.LightCount;

            for (int i = 0; i < 256; i++)
            {
                var color = sprite.Palette[i];

                var r = (int)((color >> 16) & 0xFF);
                var g = (int)((color >> 8) & 0xFF);
                var b = (int)((color >> 0) & 0xFF);
                //var a = (int)((color >> 24) & 0xFF);

                int a;

                if (i == 0)
                {
                    // transparent pixel
                    a = 0;
                }
                else if (sprite.ShadowCount > 0 && i >= shadowIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make shadows black+alpha
                        a = 64 + (((i - shadowIndex) + 1) * 16);
                        r = g = b = 0;
                    }
                    else
                    {
                        a = 255;
                    }
                }
                else if (sprite.LightCount > 0 && i >= lightIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make lights white+alpha
                        a = 64 + (((i - lightIndex) + 1) * 4);
                        r = g = b = 255;
                    }
                    else
                    {
                        a = 255;
                    }
                }

                /*else if (i > sprite.MaxSolidIndex)
                 * {
                 *  a = 0;
                 * }*/
                else
                {
                    a = 255;
                }

                palette.Entries[i] = Color.FromArgb(a, r, g, b);
            }

            this.palette = palette;

            RenderFrameAtIndex(index);

            if (sprite.Frames.Count() == 1)
            {
                btnPlayStop.Enabled = false;
            }
        }
예제 #12
0
        public static void Main(string[] args)
        {
            bool showHelp             = false;
            bool dontFixSpecialColors = false;

            var options = new OptionSet()
            {
                {
                    "ncf|no-color-fix",
                    "don't fix special colors (such as shadows, lights)",
                    v => dontFixSpecialColors = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_cfs [output_png]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string inputPath  = extras[0];
            string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".png");

            SpriteFile sprite;

            using (var input = File.OpenRead(inputPath))
            {
                sprite = new SpriteFile();
                sprite.Deserialize(input);
            }

            var bitmap = new Bitmap(
                sprite.Width * sprite.ColumnCount,
                sprite.Height * sprite.RowCount,
                PixelFormat.Format8bppIndexed);

            var palette     = bitmap.Palette;
            var shadowIndex = 256 - sprite.ShadowCount;
            var lightIndex  = shadowIndex - sprite.LightCount;

            for (int i = 0; i < 256; i++)
            {
                var color = sprite.Palette[i];

                var r = (int)((color >> 16) & 0xFF);
                var g = (int)((color >> 8) & 0xFF);
                var b = (int)((color >> 0) & 0xFF);
                //var a = (int)((color >> 24) & 0xFF);

                int a;

                if (i == 0)
                {
                    // transparent pixel
                    a = 0;
                }
                else if (sprite.ShadowCount > 0 && i >= shadowIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make shadows black+alpha
                        a = 64 + (((i - shadowIndex) + 1) * 16);
                        r = g = b = 0;
                    }
                    else
                    {
                        a = 255;
                    }
                }
                else if (sprite.LightCount > 0 && i >= lightIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make lights white+alpha
                        a = 64 + (((i - lightIndex) + 1) * 4);
                        r = g = b = 255;
                    }
                    else
                    {
                        a = 255;
                    }
                }

                /*else if (i > sprite.MaxSolidIndex)
                 * {
                 * a = 0;
                 * }*/
                else
                {
                    a = 255;
                }

                palette.Entries[i] = Color.FromArgb(a, r, g, b);
            }
            bitmap.Palette = palette;

            for (int i = 0, y = 0; y < sprite.Height * sprite.RowCount; y += sprite.Height)
            {
                for (int x = 0; x < sprite.Width * sprite.ColumnCount; x += sprite.Width)
                {
                    var frame = sprite.Frames[i++];

                    if (frame.Width == 0 ||
                        frame.Height == 0)
                    {
                        continue;
                    }

                    var area = new Rectangle(
                        x + frame.X,
                        y + frame.Y,
                        frame.Width,
                        frame.Height);

                    var data = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                    var scan = data.Scan0;
                    for (int o = 0; o < frame.Height * frame.Width; o += frame.Width)
                    {
                        Marshal.Copy(frame.Pixels, o, scan, frame.Width);
                        scan += data.Stride;
                    }
                    bitmap.UnlockBits(data);
                }
            }

            bitmap.Save(outputPath, ImageFormat.Png);
        }
예제 #13
0
        public static (Image <Rgba32>, DeviceBuffer[]) CreateSpriteAtlas(
            SpriteFile spriteFile, GraphicsDevice gd, ResourceFactory disposeFactory, TextureLoader textureLoader)
        {
            //Merge all of the sprite frames together into one texture
            //The sprite's bounds are the maximum size that a frame can be
            //Since most sprites have identical frame sizes, this lets us optimize pretty well

            //Determine how many frames to put on one line
            //This helps optimize texture size
            var framesPerLine = (int)Math.Ceiling(Math.Sqrt(spriteFile.Frames.Count));

            //Account for the change in size when converting textures
            (var maximumWith, var maximumHeight) = textureLoader.ComputeScaledSize(spriteFile.MaximumWidth, spriteFile.MaximumHeight);

            var totalWidth  = maximumWith * framesPerLine;
            var totalHeight = maximumHeight * framesPerLine;

            var atlasImage = new Image <Rgba32>(totalWidth, totalHeight);

            var graphicsOptions = GraphicsOptions.Default;

            graphicsOptions.BlenderMode = PixelBlenderMode.Src;

            var nextFramePosition = new Point();

            //Determine which texture format it is
            TextureFormat textureFormat;

            switch (spriteFile.TextureFormat)
            {
            case SpriteTextureFormat.Normal:
            case SpriteTextureFormat.Additive:
                textureFormat = TextureFormat.Normal;
                break;

            case SpriteTextureFormat.AlphaTest:
                textureFormat = TextureFormat.AlphaTest;
                break;

            default:
                textureFormat = TextureFormat.IndexAlpha;
                break;
            }

            var vertexBuffers = new List <DeviceBuffer>();

            foreach (var frame in spriteFile.Frames)
            {
                //Each individual texture is converted before being added to the atlas to avoid bleeding effects between frames
                var frameImage = textureLoader.ConvertTexture(
                    new IndexedColor256Image(spriteFile.Palette, frame.TextureData, frame.Area.Width, frame.Area.Height),
                    textureFormat);

                atlasImage.Mutate(context => context.DrawImage(graphicsOptions, frameImage, nextFramePosition));

                //Note: The frame origin does not apply to texture coordinates, only to vertex offsets
                //Important! these are float types
                PointF frameOrigin = nextFramePosition;

                var frameSize = new SizeF(frameImage.Width, frameImage.Height);

                //Convert to texture coordinates
                frameOrigin.X /= totalWidth;
                frameOrigin.Y /= totalHeight;

                frameSize.Width  /= totalWidth;
                frameSize.Height /= totalHeight;

                //The vertices should be scaled to match the frame size
                //These don't need to be modified to account for texture scale!
                var scale       = new Vector3(0, frame.Area.Width, frame.Area.Height);
                var translation = new Vector3(0, frame.Area.X, frame.Area.Y);

                //Construct the vertices
                var vertices = new WorldTextureCoordinate[]
                {
                    new WorldTextureCoordinate
                    {
                        Vertex  = (Vertices[0] * scale) + translation,
                        Texture = new Vector2(frameOrigin.X, frameOrigin.Y)
                    },
                    new WorldTextureCoordinate
                    {
                        Vertex  = (Vertices[1] * scale) + translation,
                        Texture = new Vector2(frameOrigin.X + frameSize.Width, frameOrigin.Y)
                    },
                    new WorldTextureCoordinate
                    {
                        Vertex  = (Vertices[2] * scale) + translation,
                        Texture = new Vector2(frameOrigin.X + frameSize.Width, frameOrigin.Y + frameSize.Height)
                    }
                    ,
                    new WorldTextureCoordinate
                    {
                        Vertex  = (Vertices[3] * scale) + translation,
                        Texture = new Vector2(frameOrigin.X, frameOrigin.Y + frameSize.Height)
                    }
                };

                var vb = disposeFactory.CreateBuffer(new BufferDescription(vertices.SizeInBytes(), BufferUsage.VertexBuffer));

                gd.UpdateBuffer(vb, 0, vertices);

                //TODO: could refactor this by having one vertex and one index buffer, and returning the start & count of indices for each frame
                vertexBuffers.Add(vb);

                nextFramePosition.X += maximumWith;

                //Wrap to next line
                if (nextFramePosition.X >= totalWidth)
                {
                    nextFramePosition.X  = 0;
                    nextFramePosition.Y += maximumHeight;
                }
            }

            return(atlasImage, vertexBuffers.ToArray());
        }
예제 #14
0
        public static void GenerateCFSPreview(string inputFile, string outputFile, bool dontFixSpecialColors = false)
        {
            SpriteFile sprite;

            using (var input = File.OpenRead(inputFile))
            {
                sprite = new SpriteFile();
                sprite.Deserialize(input);
            }

            var bitmap = new Bitmap(
                sprite.Width,
                sprite.Height,
                PixelFormat.Format8bppIndexed);

            var palette     = bitmap.Palette;
            var shadowIndex = 256 - sprite.ShadowCount;
            var lightIndex  = shadowIndex - sprite.LightCount;

            for (int i = 0; i < 256; i++)
            {
                var color = sprite.Palette[i];

                var r = (int)((color >> 16) & 0xFF);
                var g = (int)((color >> 8) & 0xFF);
                var b = (int)((color >> 0) & 0xFF);
                //var a = (int)((color >> 24) & 0xFF);

                int a;

                if (i == 0)
                {
                    // transparent pixel
                    a = 0;
                }
                else if (sprite.ShadowCount > 0 && i >= shadowIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make shadows black+alpha
                        a = 64 + (((i - shadowIndex) + 1) * 16);
                        r = g = b = 0;
                    }
                    else
                    {
                        a = 255;
                    }
                }
                else if (sprite.LightCount > 0 && i >= lightIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make lights white+alpha
                        a = 64 + (((i - lightIndex) + 1) * 4);
                        r = g = b = 255;
                    }
                    else
                    {
                        a = 255;
                    }
                }

                /*else if (i > sprite.MaxSolidIndex)
                 * {
                 *  a = 0;
                 * }*/
                else
                {
                    a = 255;
                }

                palette.Entries[i] = Color.FromArgb(a, r, g, b);
            }
            bitmap.Palette = palette;

            for (int i = 0, y = 0; y < sprite.Height; y += sprite.Height)
            {
                for (int x = 0; x < sprite.Width; x += sprite.Width)
                {
                    try
                    {
                        var frame = sprite.Frames[0];

                        if (frame.Width == 0 ||
                            frame.Height == 0)
                        {
                            continue;
                        }

                        var area = new Rectangle(
                            x + frame.X, y + frame.Y,
                            frame.Width, frame.Height);

                        var data = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                        var scan = data.Scan0;
                        for (int o = 0; o < frame.Height * frame.Width; o += frame.Width)
                        {
                            Marshal.Copy(frame.Pixels, o, scan, frame.Width);
                            scan += data.Stride;
                        }
                        bitmap.UnlockBits(data);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            bitmap.Save(outputFile, ImageFormat.Png);
        }
예제 #15
0
        /// <summary>
        /// Returns one or more CfsBitmaps from a given sprite file.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static List <CfsBitmap> FromSpriteFile(SpriteFile sprite, string blobName, string cfsName)
        {
            List <CfsBitmap> output = new List <CfsBitmap>();

            var bitmap = new Bitmap(sprite.Width, sprite.Height, PixelFormat.Format8bppIndexed);

            var dontFixSpecialColors = true;

            var palette     = bitmap.Palette;
            var shadowIndex = 256 - sprite.ShadowCount;
            var lightIndex  = shadowIndex - sprite.LightCount;

            // Parse the palette first.

            for (int i = 0; i < 256; i++)
            {
                var color = sprite.Palette[i];

                var r = (int)((color >> 16) & 0xFF);
                var g = (int)((color >> 8) & 0xFF);
                var b = (int)((color >> 0) & 0xFF);
                //var a = (int)((color >> 24) & 0xFF);

                int a;

                if (i == 0)
                {
                    // transparent pixel
                    a = 0;
                }
                else if (sprite.ShadowCount > 0 && i >= shadowIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make shadows black+alpha
                        a = 64 + (((i - shadowIndex) + 1) * 16);
                        r = g = b = 0;
                    }
                    else
                    {
                        a = 255;
                    }
                }
                else if (sprite.LightCount > 0 && i >= lightIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make lights white+alpha
                        a = 64 + (((i - lightIndex) + 1) * 4);
                        r = g = b = 255;
                    }
                    else
                    {
                        a = 255;
                    }
                }

                /*else if (i > sprite.MaxSolidIndex)
                 * {
                 *  a = 0;
                 * }*/
                else
                {
                    a = 255;
                }

                palette.Entries[i] = Color.FromArgb(a, r, g, b);
            }

            // Next, parse all the frames.

            for (var i = 0; i < sprite.Frames.Count(); i++)
            {
                var frame = sprite.Frames[i];

                if (frame.Width == 0 || frame.Height == 0)
                {
                    continue;
                }

                var area = new Rectangle(frame.X, frame.Y, frame.Width, frame.Height);

                bitmap = new Bitmap(sprite.Width, sprite.Height, PixelFormat.Format8bppIndexed);

                var data = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat);

                var scan = data.Scan0;

                for (int o = 0; o < frame.Height * frame.Width; o += frame.Width)
                {
                    Marshal.Copy(frame.Pixels, o, scan, frame.Width);
                    scan += data.Stride;
                }

                bitmap.UnlockBits(data);

                bitmap.Palette = palette;

                output.Add(new CfsBitmap
                {
                    Bitmap      = bitmap,
                    FrameIndex  = i,
                    BloFilename = blobName.ToLower().Trim(),
                    CfsFilename = cfsName.ToLower().Trim(),
                    SpriteFile  = sprite
                });
            }

            return(output);
        }
예제 #16
0
        private static Bitmap GenerateBitmapFromCfs(Stream s, string fileName)
        {
            bool dontFixSpecialColors = true;

            var sprite = new SpriteFile();

            sprite.Deserialize(s, fileName);

            var bitmap = new Bitmap(sprite.Width * sprite.ColumnCount,
                                    sprite.Height * sprite.RowCount, PixelFormat.Format8bppIndexed);

            var palette     = bitmap.Palette;
            var shadowIndex = 256 - sprite.ShadowCount;
            var lightIndex  = shadowIndex - sprite.LightCount;

            for (int i = 0; i < 256; i++)
            {
                var color = sprite.Palette[i];

                var r = (int)((color >> 16) & 0xFF);
                var g = (int)((color >> 8) & 0xFF);
                var b = (int)((color >> 0) & 0xFF);
                //var a = (int)((color >> 24) & 0xFF);

                int a;

                if (i == 0)
                {
                    // transparent pixel
                    a = 0;
                }
                else if (sprite.ShadowCount > 0 && i >= shadowIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make shadows black+alpha
                        a = 64 + (((i - shadowIndex) + 1) * 16);
                        r = g = b = 0;
                    }
                    else
                    {
                        a = 255;
                    }
                }
                else if (sprite.LightCount > 0 && i >= lightIndex)
                {
                    if (dontFixSpecialColors == false)
                    {
                        // make lights white+alpha
                        a = 64 + (((i - lightIndex) + 1) * 4);
                        r = g = b = 255;
                    }
                    else
                    {
                        a = 255;
                    }
                }

                /*else if (i > sprite.MaxSolidIndex)
                 * {
                 *  a = 0;
                 * }*/
                else
                {
                    a = 255;
                }

                palette.Entries[i] = Color.FromArgb(a, r, g, b);
            }
            bitmap.Palette = palette;

            for (int i = 0, y = 0; y < sprite.Height * sprite.RowCount; y += sprite.Height)
            {
                for (int x = 0; x < sprite.Width * sprite.ColumnCount; x += sprite.Width)
                {
                    var frame = sprite.Frames[i++];

                    if (frame.Width == 0 || frame.Height == 0)
                    {
                        continue;
                    }

                    var area = new Rectangle(
                        x + frame.X, y + frame.Y,
                        frame.Width, frame.Height);

                    var data = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                    var scan = data.Scan0;
                    for (int o = 0; o < frame.Height * frame.Width; o += frame.Width)
                    {
                        Marshal.Copy(frame.Pixels, o, scan, frame.Width);
                        scan += data.Stride;
                    }
                    bitmap.UnlockBits(data);
                }
            }

            return(bitmap);
        }