示例#1
0
        private void chooseTileset_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.Title           = "Select file";
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.CheckPathExists = true;

            openFileDialog1.Filter = "Nitro Tileset (*.nbfc)|*.nbfc";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                activeNbfc           = new nbfcTilesetFile();
                activeNbfc.form1     = form1;
                activeNbfc.filepath  = openFileDialog1.FileName;
                activeNbfc.filebytes = File.ReadAllBytes(activeNbfc.filepath);
                activeNbfc.Load();
            }
        }
示例#2
0
        private void importFromPNG_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.Title           = "Select image file";
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.CheckPathExists = true;

            openFileDialog1.Filter = "PNG image (*.png)|*.png";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                activeNbfc = new nbfcTilesetFile();
                activeNbfs = new mpbfile();
                activeNbfp = new nbfpfile();
                // activeNbfs.editorForm = this;

                Bitmap image = (Bitmap)Image.FromFile(openFileDialog1.FileName);

                //check dimensions
                if (image.Width % 8 != 0)
                {
                    MessageBox.Show("Image width must be a multiple of 8.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                if (image.Height % 8 != 0)
                {
                    MessageBox.Show("Image height must be a multiple of 8.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                //check palette
                List <Color> palette = new List <Color>();

                for (int y = 0; y < image.Height; y++)
                {
                    for (int x = 0; x < image.Width; x++)
                    {
                        Color newColour = image.GetPixel(x, y);

                        if (!palette.Contains(newColour))
                        {
                            palette.Add(newColour);
                        }

                        if (palette.Count > 256)
                        {
                            MessageBox.Show("The image must not have more than 256 colours.", "Too many colours", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                    }
                }

                if (palette.Count < 256 && !palette.Contains(Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF)) && !palette.Contains(Color.FromArgb(0x00, 0xFF, 0x00, 0xFF)))  //if there's space for it, sneakily add the magenta alpha anyway
                {
                    palette.Add(Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF));
                }

                MessageBox.Show("Alpha colour is enforced as RGB 0xFF00FF (a bright magenta). If you want transparency in your image, use this colour.", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);

                TSBAlphaColour = Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF);

                //swap the alpha colour to the start

                for (int c = 0; c < palette.Count; c++)
                {
                    if ((palette[c].R & 0xF8) == (TSBAlphaColour.R & 0xF8) && (palette[c].G & 0xF8) == (TSBAlphaColour.G & 0xF8) && (palette[c].B & 0xF8) == (TSBAlphaColour.B & 0xF8))
                    {
                        //swap the first slot colour here, and put the alpha colour in the first slot instead
                        palette[c] = palette[0];
                        palette[0] = TSBAlphaColour;
                        break;
                    }
                }

                //truncate colours

                TSBAlphaColour = Color.FromArgb(0xFF, TSBAlphaColour.R & 0xF8, TSBAlphaColour.G & 0xF8, TSBAlphaColour.B & 0xF8);

                for (int c = 0; c < palette.Count; c++)
                {
                    palette[c] = Color.FromArgb(0xFF, palette[c].R & 0xF8, palette[c].G & 0xF8, palette[c].B & 0xF8);
                }

                //turn image into tiles

                activeNbfp.palette = palette.ToArray();

                byte[] NBFCimage = (form1.ImageToNBFC(image, 8, activeNbfp.palette));

                NBFCimage.Reverse();

                List <Tile> tiles = new List <Tile>();

                int width_in_tiles  = image.Width / 8;
                int height_in_tiles = image.Height / 8;

                int pos = 0;


                List <Tile> uniqueTiles = new List <Tile>();

                for (int y = 0; y < height_in_tiles; y++)
                {
                    for (int x = 0; x < width_in_tiles; x++)
                    {
                        //make a new tile from the current pos in the image
                        Tile newTile = new Tile();

                        for (int i = 7; i >= 0; i--)
                        {
                            Array.Copy(NBFCimage, pos + (image.Width * i), newTile.tileImage, 8 * i, 8);
                        }

                        //now that we have the tile, compare it to the other tiles

                        for (int t = 0; t < tiles.Count; t++)
                        {
                            if (tiles[t].hasSimilarTile)    //only use tiles that aren't already references to other tiles
                            {
                                continue;
                            }

                            int tileSimilarlity = AreTilesSimilar(newTile, tiles[t]);

                            if (tileSimilarlity > 0) //if they are similar (i.e. identical but one of them is a mirror of the other)
                            {
                                newTile.hasSimilarTile = true;
                                newTile.SimilarTile    = tiles[t];

                                if (tileSimilarlity == 1)   //then they are just the same tile
                                {
                                }
                                else if (tileSimilarlity == 2)   //then they are the same but one of them is X flipped
                                {
                                    newTile.flipX = true;
                                }
                                else if (tileSimilarlity == 3)   //then they are the same but one of them is Y flipped
                                {
                                    newTile.flipY = true;
                                }
                                else if (tileSimilarlity == 4)   //then they are the same but one of them is flipped on both X and Y
                                {
                                    newTile.flipX = true;
                                    newTile.flipY = true;
                                }
                                break;
                            }
                        }

                        if (!newTile.hasSimilarTile)
                        {
                            uniqueTiles.Add(newTile);
                        }

                        tiles.Add(newTile);
                        pos += 8;
                    }

                    if (pos % image.Width == 0)
                    {
                        pos += image.Width * 7;
                    }
                }

                //now we should have a list of tiles, some of which are mirrors of each other if applicable


                activeNbfc.filebytes = new byte[uniqueTiles.Count * 64];

                //now write palette to nbfp

                activeNbfp.filebytes = new byte[0x200];

                for (int c = 0; c < palette.Count; c++)
                {
                    ushort ABGR1555Colour = form1.ColorToABGR1555(palette[c]);

                    activeNbfp.filebytes[(c * 2)]     = (byte)ABGR1555Colour;
                    activeNbfp.filebytes[(c * 2) + 1] = (byte)(ABGR1555Colour >> 8);
                }

                //now write tiles to tsb, but only the ones that are their own tile and not just referencing another one



                int tileWritingPos = 0x00;

                for (int t = 0; t < uniqueTiles.Count; t++)
                {
                    if (!uniqueTiles[t].hasSimilarTile)   //only process it if it's a master tile
                    {
                        foreach (Byte b in uniqueTiles[t].tileImage)
                        {
                            activeNbfc.filebytes[tileWritingPos] = b;
                            tileWritingPos++;
                        }
                    }
                }

                //MPB

                activeNbfs.filebytes = new byte[tiles.Count * 2];


                for (int t = 0; t < tiles.Count; t++)
                {
                    ushort tileDescriptor = 0;

                    if (tiles[t].hasSimilarTile)
                    {
                        //then write a reference to the similar tile instead

                        tileDescriptor = (ushort)uniqueTiles.IndexOf(tiles[t].SimilarTile);


                        if (tiles[t].flipX)
                        {
                            tileDescriptor |= 0x0400;
                        }

                        if (tiles[t].flipY)
                        {
                            tileDescriptor |= 0x0800;
                        }
                    }
                    else    //otherwise, just write this tile normally
                    {
                        tileDescriptor = (ushort)uniqueTiles.IndexOf(tiles[t]);
                    }

                    activeNbfs.filebytes[(t * 2)]     = (byte)tileDescriptor;
                    activeNbfs.filebytes[(t * 2) + 1] = (byte)(tileDescriptor >> 8);
                }

                LoadBoth();
            }
        }