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(); }
private Bitmap DrawBullet(Bitmap image, Animation animation, bool flip, int zoom) { var width = image.Width; var height = image.Height; var xOff = Constants.SpriteWidth * zoom; var yOff = Constants.SpriteHeight * zoom; var newImage = new MyBitmap(width + xOff * 2, height + yOff * 2, this.pictureBox.BackColor); newImage.DrawImage(MyBitmap.FromBitmap(image), xOff, yOff); if (animation.Offsets.GunXOff >= 0) { var bullet = this.bulletConfig.Bullets.First(b => b.BulletId == animation.BulletId); var flipFlags = bullet.GetFlipFlags(flip); var bulletBitmap = bullet.Sprite.GetSprite( this.applyPaletteCheckbox.Checked, flipFlags.HasFlag(ImageFlags.VFlip), flipFlags.HasFlag(ImageFlags.HFlip), this.pictureBox.BackColor).Clone(); var scaled = bulletBitmap.Scale(zoom); if (flip) { newImage.DrawImage( scaled, xOff + animation.Offsets.GunXOffFlip * zoom, yOff + animation.Offsets.GunYOffFlip * zoom); } else { newImage.DrawImage( scaled, xOff + animation.Offsets.GunXOff * zoom, yOff + animation.Offsets.GunYOff * zoom); } } return(newImage.ToBitmap()); }
private void LoadButtonClick(object sender, System.EventArgs e) { this.story = Story.Read(this.storyTextBox.Text); this.stringsConfig = StringsConfig.Read(this.stringsTextBox.Text); var tiles = new List<MyBitmap>(); TitleDialog.ProcessFont(this.fontTextBox.Text, tiles); var strings = new List<StringToRedner>(); foreach (var strData in this.story.Strings) { if (strData.X < 1 || strData.Y < 1) { throw new System.Exception("Invalid string position"); } var str = this.stringsConfig.Strings.First(s => s.Id == strData.StringId).Value; if (str.Length > 30) { throw new System.Exception("Invalid string length"); } strings.Add(new StringToRedner(strData.X, strData.Y, str.ToLower())); } strings.Add(new StringToRedner(PressStartX, PressStartY, PressStart)); var bmp = new MyBitmap(512, 448, System.Drawing.Color.Black); // 448 means NTSC foreach (var str in strings) { var x = str.X; foreach (var chr in str.Str.ToCharArray()) { var tile = tiles[TitleDialog.Chars.IndexOf(chr)].Scale(BitmapZoom); bmp.DrawImage(tile, x * Constants.SpriteWidth * BitmapZoom, (str.Y - 1) * Constants.SpriteHeight * BitmapZoom); // - 1 because of NTSC x++; } } this.pictureBox.Image = bmp.ToBitmap(); }
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(); }
private void GenerateChrImageAndSaveFiles(BackgroundConfig config, List <MyBitmap> sprites) { // Find the empty tile, move it to the end, update the config int emptyTileIndex = -1; for (var i = 0; i < sprites.Count; i++) { if (sprites[i].IsNesColor(0)) { emptyTileIndex = i; } } if (emptyTileIndex == -1) { throw new Exception("Empty tile not found for some reason"); } // Move empty tile to the beginning. var emptyTile = sprites[emptyTileIndex]; sprites.RemoveAt(emptyTileIndex); var newEmptyTileIndex = 0; sprites.Insert(0, emptyTile); // Update the config. foreach (var tile in config.Tiles) { var newSprites = new int[4]; Array.Copy(tile.Sprites, newSprites, 4); for (var i = 0; i < 4; i++) { if (newSprites[i] == emptyTileIndex) { newSprites[i] = newEmptyTileIndex; } else if (newSprites[i] < emptyTileIndex) { newSprites[i] = newSprites[i] + 1; } } tile.Sprites = newSprites; } // Generate chr image var chrImage = new MyBitmap(Constants.SpriteWidth * Constants.ChrFileSpritesPerRow, Constants.SpriteHeight * Constants.ChrFileRows, Color.Black); { var x = 0; var y = 0; foreach (var sprite in sprites) { chrImage.DrawImage(sprite, x, y); x += 8; if (x >= Constants.SpriteWidth * Constants.ChrFileSpritesPerRow) { x = 0; y += 8; } } } // Generate actual chr file // CHR format: // each sprite is 16 bytes: // first 8 bytes are low bits per sprite row // second 8 bytes are high bits per sprite row var bytes = new List <byte>(); foreach (var sprite in sprites) { 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 = sprite.GetNesPixel(x, y); if (pixel == 1 || pixel == 3) { // low bit set lowBit |= 1; } if (pixel == 2 || pixel == 3) { // high bit set highBit |= 1; } } lowBits.Add(lowBit); highBits.Add(highBit); } bytes.AddRange(lowBits); bytes.AddRange(highBits); } while (bytes.Count < 4096) { bytes.Add(0); } // Save everything chrImage.ToBitmap().Save(outputImageTextBox.Text); config.Write(outputSpecTextBox.Text); if (File.Exists(outputChrTextBox.Text)) { File.Delete(outputChrTextBox.Text); } File.WriteAllBytes(outputChrTextBox.Text, bytes.ToArray()); }