示例#1
0
        private void Redraw()
        {
            if (this.disableRedrawing)
            {
                return;
            }

            var selectedSpec    = this.config.GetSpecById((int)this.tilesetComboBox.SelectedItem);
            var selectedPalette = this.palettes.BackgroundPalettes.First(p => p.Id == (int)this.paletteComboBox.SelectedItem);

            var bgSpec      = selectedSpec.GetBgSpec();
            var blocking    = MyBitmap.FromFile(bgSpec.BlockingFile).Scale(2);
            var nonBlocking = MyBitmap.FromFile(bgSpec.NonBlockingFile).Scale(2);
            var threats     = MyBitmap.FromFile(bgSpec.ThreatFile).Scale(2);

            var packed = Packer.Pack(new Size[] { blocking.Size, nonBlocking.Size, threats.Size }, maxWidth);

            var width  = packed.Max(tpl => tpl.Item1.X + tpl.Item2.Width);
            var height = packed.Max(tpl => tpl.Item1.Y + tpl.Item2.Height);

            var blockingPosition = packed.First(tpl => tpl.Item2 == blocking.Size);

            packed.Remove(blockingPosition);
            var nonBlockingPosition = packed.First(tpl => tpl.Item2 == nonBlocking.Size);

            packed.Remove(nonBlockingPosition);
            var threatsPosition = packed.First(); // only one left

            var palette = this.palettes.BackgroundPalettes[this.SelectedPalette];
            var bgColor = palette.Palettes.First().ActualColors.First();

            var bigBitmap = new MyBitmap(2 * width + 30, 2 * height + 30, bgColor);

            for (var i = 0; i <= 3; i++)
            {
                var bitmap = new MyBitmap(width, height, bgColor);

                var blockingClone = blocking.Clone();
                blockingClone.UpdateColors(blockingClone.UniqueColors(), palette.Palettes[i].ActualColors);
                var nonBlockingClone = nonBlocking.Clone();
                nonBlockingClone.UpdateColors(nonBlockingClone.UniqueColors(), palette.Palettes[i].ActualColors);
                var threatsClone = threats.Clone();
                threatsClone.UpdateColors(threatsClone.UniqueColors(), palette.Palettes[i].ActualColors);

                bitmap.DrawImage(blockingClone, blockingPosition.Item1.X, blockingPosition.Item1.Y);
                bitmap.DrawImage(nonBlockingClone, nonBlockingPosition.Item1.X, nonBlockingPosition.Item1.Y);
                bitmap.DrawImage(threatsClone, threatsPosition.Item1.X, threatsPosition.Item1.Y);

                bigBitmap.DrawImage(bitmap, 10 + (i % 2) * (bitmap.Width + 10), 10 + (i / 2) * (bitmap.Height + 10));
            }

            this.pictureBox.Image = bigBitmap.ToBitmap();

            var newWidth  = Math.Max(bigBitmap.Width, minWidth);
            var newHeight = bigBitmap.Height + heightOffset;

            this.Width  = newWidth + widthOffset;
            this.Height = Math.Min(newHeight, maxHeight);
            this.Refresh();
        }
示例#2
0
        private void LoadDirectory()
        {
            this.images = new Dictionary <string, Bitmap>();
            var directory = new DirectoryInfo(this.directoryTextBox.Text);

            int?width  = null;
            int?height = null;

            foreach (var file in directory.EnumerateFiles().OrderBy(f => f.Name))
            {
                int ignore;
                if (!int.TryParse(file.Name.Substring(0, file.Name.Length - file.Extension.Length), out ignore))
                {
                    continue;
                }

                var image = MyBitmap.FromFile(file.FullName);

                if (width == null)
                {
                    width = image.Width;
                }
                else if (width != image.Width)
                {
                    throw new Exception("Invalid width " + file.Name);
                }

                if (height == null)
                {
                    height = image.Height;
                }
                else if (height != image.Height)
                {
                    throw new Exception("Invalid height " + file.Name);
                }

                this.images.Add(file.Name, image.Scale((int)this.zoomPicker.Value).ToBitmap());
            }

            this.framesListBox.Items.Clear();
            foreach (var item in images.Keys)
            {
                this.framesListBox.Items.Add(item);
            }

            this.StartAnimation();
        }
示例#3
0
        public static void ProcessFont(string fontBmp, IList <MyBitmap> tiles, IList <int> atts = null)
        {
            var emptyFound       = false;
            var secondEmptyFound = false;
            var fontBitmap       = MyBitmap.FromFile(fontBmp);

            for (var y = 0; y < fontBitmap.Height; y += Constants.SpriteHeight)
            {
                for (var x = 0; x < fontBitmap.Width; x += Constants.SpriteWidth)
                {
                    var part = fontBitmap.GetPart(x, y, Constants.SpriteWidth, Constants.SpriteHeight);
                    if (part.IsSolidColor(part.GetPixel(0, 0)))
                    {
                        if (!emptyFound)
                        {
                            emptyFound = true;
                            tiles.Add(part);
                            if (atts != null)
                            {
                                atts.Add(1);
                            }
                        }
                        else
                        {
                            secondEmptyFound = true;
                        }
                    }
                    else
                    {
                        if (secondEmptyFound)
                        {
                            throw new Exception("Empty font tile in the middle of other tiles");
                        }

                        tiles.Add(part);
                        if (atts != null)
                        {
                            atts.Add(1);
                        }
                    }
                }
            }
        }
示例#4
0
 public MyBitmap GetChrImage() => MyBitmap.FromFile(this.ChrImagePath());
示例#5
0
文件: Tiles.cs 项目: sav-dev/NonStop
        private void LoadButtonClick(object sender, EventArgs e)
        {
            var fileName = this.inputTextBox.Text;

            if (!File.Exists(fileName))
            {
                MessageBox.Show("File doesn't exit");
            }

            this.bitmap = MyBitmap.FromFile(fileName);

            if (this.bitmap.Width != Constants.BgWidth || this.bitmap.Height != Constants.BgHeight)
            {
                MessageBox.Show($"Incorrect size, should be {Constants.BgWidth}x{Constants.BgHeight}");
            }

            this.tiles     = new List <MyBitmap>();
            this.positions = new List <Point>();
            var indices = new int[32, 24];

            for (var y = 0; y < this.bitmap.Height / Constants.NesTileSize; y++)
            {
                for (var x = 0; x < this.bitmap.Width / Constants.NesTileSize; x++)
                {
                    var smallImage = bitmap.GetPart(x * Constants.NesTileSize, y * Constants.NesTileSize, Constants.NesTileSize, Constants.NesTileSize);
                    if (this.tiles.Any(v => v.Equals(smallImage)))
                    {
                        indices[x, y] = this.tiles.IndexOf(smallImage);
                    }
                    else
                    {
                        this.tiles.Add(smallImage);
                        this.positions.Add(new Point(x * Constants.NesTileSize, y * Constants.NesTileSize));
                        indices[x, y] = this.tiles.Count - 1;
                    }
                }
            }

            const int entryWidth        = 65;
            const int horizontalSpacing = 8;
            const int entriesInRow      = 7;
            const int leftPadding       = 12;
            const int imageWidth        = entryWidth + (entryWidth + horizontalSpacing) * (entriesInRow - 1) + leftPadding;
            const int entryHeight       = 33;
            const int verticalSpacing   = 2;
            const int topPadding        = 12;
            var       rowCount          = (this.tiles.Count + entriesInRow - 1) / entriesInRow;
            var       imageHeight       = rowCount * entryHeight + (rowCount - 1) * verticalSpacing + topPadding;

            this.smallImagesBitmap = new MyBitmap(imageWidth, imageHeight);

            var font = new Font("Calibri", 8);

            for (var i = 0; i < this.tiles.Count; i++)
            {
                var x        = (i % entriesInRow) * (entryWidth + horizontalSpacing) + leftPadding;
                var y        = (i / entriesInRow) * (entryHeight + verticalSpacing) + topPadding;
                var tile     = this.tiles[i].Scale(2);
                var subImage = new MyBitmap(entryWidth, entryHeight);
                subImage.DrawImage(tile, (entryWidth - tile.Width) / 2, 0);

                var tempBitmap = subImage.ToBitmap();
                using (var g = Graphics.FromImage(tempBitmap))
                {
                    g.DrawString(string.Format("{0:D3}: {1:D3}/{2:D3}", i, this.positions[i].X, this.positions[i].Y), font, Brushes.Black, 0, 18);
                }

                this.smallImagesBitmap.DrawImage(MyBitmap.FromBitmap(tempBitmap), x, y);
            }

            this.smallImagesPanel.BackgroundImage = this.smallImagesBitmap.ToBitmap();

            var str = string.Empty;

            for (var y = 0; y < this.bitmap.Height / Constants.NesTileSize; y++)
            {
                for (var x = 0; x < this.bitmap.Width / Constants.NesTileSize; x++)
                {
                    str += indices[x, y].ToString("D3") + " ";
                }

                str += Environment.NewLine;
            }

            this.textBox.Text = str;
            this.UpdateImage();
        }
示例#6
0
        private void GetConfigAndSprites(
            string nonBlockingFile,
            string blockingFile,
            string threatFile,
            bool handleEmptyTile,
            out BackgroundConfig configRes,
            out List <MyBitmap> spritesRes,
            out Dictionary <string, MyBitmap> tilesWithImagesRes)
        {
            // Create config with file names.
            var config = new BackgroundConfig
            {
                NonBlockingFile = nonBlockingFile,
                BlockingFile    = blockingFile,
                ThreatFile      = threatFile
            };

            // Get all files. Handle some not existing.
            var nonBlocking = File.Exists(nonBlockingFile) ? MyBitmap.FromFile(config.NonBlockingFile) : null;
            var blocking    = File.Exists(blockingFile) ? MyBitmap.FromFile(config.BlockingFile) : null;
            var threat      = File.Exists(threatFile) ? MyBitmap.FromFile(config.ThreatFile) : null;

            // Get all tiles and sprites
            var allTiles        = new List <MyBitmap>();
            var tiles           = new List <Tile>();
            var sprites         = new List <MyBitmap>();
            var tilesWithImages = new Dictionary <string, MyBitmap>();

            // Processing function
            Tile emptyTile = null;
            Action <MyBitmap, TileType> processList = (bitmap, tileType) =>
            {
                bitmap.MakeNesGreyscale();

                for (var x = 0; x < bitmap.Width; x += Constants.BackgroundTileWidth)
                {
                    for (var y = 0; y < bitmap.Height; y += Constants.BackgroundTileHeight)
                    {
                        var newTile     = bitmap.GetPart(x, y, Constants.BackgroundTileWidth, Constants.BackgroundTileHeight);
                        var isEmptyTile = newTile.IsNesColor(0);
                        if (allTiles.Any(tile => tile.Equals(newTile)))
                        {
                            if (!isEmptyTile)
                            {
                                throw new Exception(string.Format("Tile {0}/{1} in file {2} is repeated somewhere", x, y, bitmap.FileName));
                            }

                            continue;
                        }

                        if (isEmptyTile && tileType != TileType.NonBlocking)
                        {
                            throw new Exception("Empty tile found first in file other than non-blocking");
                        }

                        var tileConfig = new Tile
                        {
                            Type = tileType,
                            X    = x / Constants.BackgroundTileWidth,
                            Y    = y / Constants.BackgroundTileHeight
                        };

                        if (isEmptyTile)
                        {
                            emptyTile = tileConfig;
                        }

                        tileConfig.Sprites = new int[4];

                        var spritesInTile = new MyBitmap[]
                        {
                            newTile.GetPart(0, 0, Constants.SpriteWidth, Constants.SpriteHeight),
                            newTile.GetPart(0, Constants.SpriteHeight, Constants.SpriteWidth, Constants.SpriteHeight),
                            newTile.GetPart(Constants.SpriteWidth, 0, Constants.SpriteWidth, Constants.SpriteHeight),
                            newTile.GetPart(Constants.SpriteWidth, Constants.SpriteHeight, Constants.SpriteWidth, Constants.SpriteHeight),
                        };

                        for (var i = 0; i < spritesInTile.Length; i++)
                        {
                            var sprite         = spritesInTile[i];
                            var indexOfSprite  = -1;
                            var spriteFromList = sprites.FirstOrDefault(s => s.Equals(sprite));

                            if (spriteFromList != null)
                            {
                                indexOfSprite = sprites.IndexOf(spriteFromList);
                            }
                            else
                            {
                                sprites.Add(sprite);
                                indexOfSprite = sprites.Count - 1;
                            }

                            tileConfig.Sprites[i] = indexOfSprite;
                        }

                        tiles.Add(tileConfig);
                        allTiles.Add(newTile);

                        tilesWithImages.Add(tileConfig.Id, newTile);
                    }
                }
            };

            // Process all tiles (non blocking first)
            if (nonBlocking != null)
            {
                processList(nonBlocking, TileType.NonBlocking);
            }

            if (blocking != null)
            {
                processList(blocking, TileType.Blocking);
            }

            if (threat != null)
            {
                processList(threat, TileType.Threat);
            }

            // Move empty tile to the 1st place
            if (handleEmptyTile)
            {
                if (emptyTile == null)
                {
                    throw new Exception("Empty tile not found");
                }

                tiles.Remove(emptyTile);
                tiles.Insert(0, emptyTile);
            }

            // Set tiles in the config
            config.Tiles = tiles.ToArray();

            // Set results.
            configRes          = config;
            spritesRes         = sprites;
            tilesWithImagesRes = tilesWithImages;
        }
示例#7
0
        public static SpriteConfig Read(string file, Palettes palettes)
        {
            // Read the XML.
            SpriteConfig config;
            var          xml           = File.ReadAllText(file);
            var          xmlSerializer = new XmlSerializer(typeof(SpriteConfig));

            using (var memoryStream = new MemoryStream())
            {
                using (var streamWriter = new StreamWriter(memoryStream))
                {
                    streamWriter.Write(xml);
                    streamWriter.Flush();
                    memoryStream.Position = 0;
                    config = (SpriteConfig)xmlSerializer.Deserialize(memoryStream);
                }
            }

            // Get the image (same name).
            var sourceImagePath = file.Substring(0, file.Length - 3) + "png";
            var source          = MyBitmap.FromFile(sourceImagePath);

            // Prepare all sprites.
            foreach (var sprite in config.Sprites)
            {
                // Prepare sprite - get the image.
                sprite.PrepareSprite(source);

                // Validate number of unique colors.
                var uniqueColors = sprite.GetSprite().UniqueColors();
                if (uniqueColors.Length > 4)
                {
                    sprite.GetSprite().ToBitmap().Save("debug.bmp");
                    throw new Exception(string.Format("Too many colors in sprite {0}", sprite.Id));
                }

                // Get and validate the palette mapping.
                var mapping = config.PaletteMappings.First(m => m.Id == sprite.Mapping);
                foreach (var color in uniqueColors)
                {
                    if (!mapping.ColorMappings.Select(c => c.Color).Contains(color))
                    {
                        sprite.GetSprite().ToBitmap().Save("debug.bmp");
                        throw new Exception(string.Format("Color not mapped in sprite {0}", sprite.Id));
                    }
                }

                // Prepare sprite with pallete applied and all reverse combinations.
                sprite.PreparePalettes(palettes, mapping);
                sprite.PrepareReversed();
            }

            // Prepare frames.
            foreach (var frame in config?.Frames ?? new Frame[0])
            {
                foreach (var sprite in frame.Sprites)
                {
                    if (sprite.Id != -1)
                    {
                        sprite.ActualSprite = config.Sprites.First(s => s.Id == sprite.Id);
                    }
                    else
                    {
                        sprite.IsEmpty = true;
                    }
                }
            }

            // Prepare animations.
            foreach (var animation in config.Animations ?? new Animation[0])
            {
                // No copy of animation 0 possible since it defaults to 0
                if (animation.CopyOf > 0)
                {
                    var copyFrom = config.Animations.First(a => a.Id == animation.CopyOf);

                    //// Essentially what's happening here is we clone the animation, frames and sprites and change the palette

                    // Copy everything except for Frames.
                    animation.SetFrom(copyFrom);

                    // Now we must copy Frames.
                    var newFrames = new List <Frame>();
                    foreach (var frame in copyFrom.Frames)
                    {
                        var frameClone = frame.Clone();
                        foreach (var sprite in frameClone.Sprites)
                        {
                            var mapping = config.PaletteMappings.First(m => m.Id == sprite.ActualSprite.Mapping);
                            sprite.ActualSprite.PreparePalettes(palettes, mapping, animation.AttsUpdate);
                            sprite.ActualSprite.PrepareReversed();
                        }

                        newFrames.Add(frameClone);
                    }

                    animation.Frames = newFrames.ToArray();
                    continue;
                }

                for (var i = 0; i < animation.Frames.Length; i++)
                {
                    animation.Frames[i] = config.Frames.First(frame => frame.Id == animation.Frames[i].Id);
                }
            }

            // Prepare bullets
            foreach (var bullet in config?.Bullets ?? new Bullet[0])
            {
                bullet.Sprite = config.Sprites.First(s => s.Id == bullet.SpriteId);
            }

            return(config);
        }
示例#8
0
        private void ProcessButtonClick(object sender, EventArgs e)
        {
            var tiles   = new List <MyBitmap>();
            var atts    = new List <int>();
            var bgColor = Color.Black;

            // Font
            ProcessFont(this.fontTextBox.Text, tiles, atts);
            if (tiles.Count != Chars.Count)
            {
                throw new Exception("Invalid number of tiles in the font bmp");
            }

            // Logo
            var logo = MyBitmap.FromFile(this.logoTextBox.Text);
            var ids  = new int[logo.Width / Constants.SpriteWidth, logo.Height / Constants.SpriteHeight];

            for (var y = 0; y < logo.Height; y += Constants.SpriteHeight)
            {
                for (var x = 0; x < logo.Width; x += Constants.SpriteWidth)
                {
                    var tile = logo.GetPart(x, y, Constants.SpriteWidth, Constants.SpriteHeight);
                    if (!tiles.Any(t => t.Equals(tile)))
                    {
                        tiles.Add(tile);
                        atts.Add(3);
                    }

                    ids[x / Constants.SpriteWidth, y / Constants.SpriteHeight] = tiles.IndexOf(tile);
                }
            }

            // Cursor.
            var cursor   = MyBitmap.FromFile(this.cursorTextBox.Text);
            var cursorId = tiles.Count;

            tiles.Add(cursor);
            atts.Add(2);

            // Create CHR.
            // 1st empty sprite
            var bytes = new List <byte>();

            for (var i = 0; i < tiles.Count; i++)
            {
                var tile        = tiles[i];
                var attsForTile = atts[i];

                var lowBits  = new List <byte>();
                var highBits = new List <byte>();

                for (var y = 0; y < Constants.SpriteHeight; y++)
                {
                    byte lowBit  = 0;
                    byte highBit = 0;

                    for (var x = 0; x < Constants.SpriteWidth; x++)
                    {
                        lowBit  = (byte)(lowBit << 1);
                        highBit = (byte)(highBit << 1);

                        var pixel = tile.GetPixel(x, y).ToArgb();
                        if (pixel != bgColor.ToArgb())
                        {
                            if (attsForTile == 1 || attsForTile == 3)
                            {
                                lowBit |= 1;
                            }

                            if (attsForTile == 2 || attsForTile == 3)
                            {
                                highBit |= 1;
                            }
                        }
                    }

                    lowBits.Add(lowBit);
                    highBits.Add(highBit);
                }

                bytes.AddRange(lowBits);
                bytes.AddRange(highBits);
            }

            bytes.AddRange(Enumerable.Repeat((byte)0, 4096 - bytes.Count));
            File.WriteAllBytes(chrOutputTextBox.Text, bytes.ToArray());

            // Get code.
            var code = this.GetCode(logo, ids, cursorId);

            new CodeWindow(code).ShowDialog();
        }