예제 #1
0
        private void btnLZForceCompression_Click(object sender, EventArgs e)
        {
            NitroFile file = Program.m_ROM.GetFileFromName(m_SelectedFile);

            try
            {
                file.ForceCompression();
            }
            catch (Exception ex)
            {
                MessageBox.Show("There was an error trying to compress the file \"" + file.m_Name + "\" with " +
                                "LZ77 compression (no header)\n\n" + ex.Message + "\n\n" + ex.StackTrace);
            }
            file.SaveChanges();
        }
예제 #2
0
        public void SwitchBackground(int swapped)
        {
            m_PalFile = Program.m_ROM.GetFileFromName(txtSelNCL.Text);
            //The background colour is the first colour stored in the palette
            ushort first         = m_PalFile.Read16((uint)0);             //Read the first colour in the palette file
            ushort swappedColour = m_PalFile.Read16((uint)(swapped * 2)); //Read the colour to be swapped

            //Colour in BGR15 format (16 bits) written to every even address 0,2,4...
            m_PalFile.Write16((uint)0, swappedColour);     //Write new background colour to first entry
            m_PalFile.Write16((uint)(swapped * 2), first); //Write the previously first colour to the colour being swapped

            m_PalFile.SaveChanges();

            //Swap all palette file entries for the swapped colours in the graphic file
            m_TileSetFile = Program.m_ROM.GetFileFromName(txtSelNCG.Text);
            if (chkNCGDcmp.Checked)
            {
                m_TileSetFile.ForceDecompression();
            }
            uint   tileoffset = 0, tilenum = 0;
            ushort tilecrap = 0;

            for (int my = 0; my < m_SizeY; my += 8)
            {
                for (int mx = 0; mx < m_SizeX; mx += 8)
                {
                    if (m_IsUsingTileMap)
                    {
                        tilecrap = m_TileMapFile.Read16(tileoffset);
                        tilenum  = (uint)(tilecrap & 0x03FF);
                    }

                    for (int ty = 0; ty < 8; ty++)
                    {
                        for (int tx = 0; tx < 8; tx++)
                        {
                            if (m_BPP == 8)
                            {
                                uint totaloffset = (uint)(tilenum * 64 + ty * 8 + tx);  //Position of current pixel's entry
                                byte palentry    = m_TileSetFile.Read8(totaloffset);
                                if (palentry == 0)                                      //If the current pixel points to first colour in palette,
                                {
                                    m_TileSetFile.Write8(totaloffset, (byte)(swapped)); //point it to the swapped colour
                                }
                                if (palentry == (byte)swapped)                          //If the current pixel points to the swapped colour in palette,
                                {
                                    m_TileSetFile.Write8(totaloffset, (byte)0);         //point it to the first colour
                                }
                            }
                            else if (m_BPP == 4)
                            {
                                float totaloffset = (float)((float)(tilenum * 64 + ty * 8 + tx) / 2f);//Address of current pixel
                                byte  palentry    = 0;
                                if (totaloffset % 1 == 0)
                                {
                                    // Right 4 bits
                                    palentry = m_TileSetFile.Read8((uint)totaloffset);                                                              //Offset of current pixel's entry in palette file
                                    palentry = (byte)(palentry & 0x0F);                                                                             // Get 4 right bits
                                    if (palentry == 0)                                                                                              //If the current pixel points to first colour in palette,
                                    {
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((m_TileSetFile.Read8((uint)totaloffset) & 0xF0) | swapped)); //point it to the swapped colour
                                    }
                                    if (palentry == (byte)swapped)                                                                                  //If the current pixel points to the swapped colour in palette,
                                    {
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((m_TileSetFile.Read8((uint)totaloffset) & 0xF0) | 0));       //point it to the first colour
                                    }
                                }
                                else
                                {
                                    // Left 4 bits
                                    palentry = m_TileSetFile.Read8((uint)totaloffset);                                                                     //Offset of current pixel's entry in palette file
                                    palentry = (byte)(palentry >> 4);
                                    if (palentry == 0)                                                                                                     //If the current pixel points to first colour in palette,
                                    {
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((swapped << 4) | (m_TileSetFile.Read8((uint)totaloffset) & 0x0F))); //point it to the swapped colour
                                    }
                                    if (palentry == (byte)swapped)                                                                                         //If the current pixel points to the swapped colour in palette,
                                    {
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)(0 | (m_TileSetFile.Read8((uint)totaloffset) & 0x0F)));              //point it to the first colour
                                    }
                                }
                            }
                        }
                    }

                    tileoffset += 2;
                    if (!m_IsUsingTileMap)
                    {
                        tilenum++;
                    }
                }
            }

            if (chkNCGDcmp.Checked)
            {
                m_TileSetFile.ForceCompression();
            }
            m_TileSetFile.SaveChanges();

            RedrawMinimap(m_IsUsingTileMap, m_SizeX, m_SizeY, m_BPP, m_PaletteRow);
        }
예제 #3
0
        public void ImportBMP(string filename, int bpp, int sizeX, int sizeY, bool replaceMinimap = false, int numTilesX = 0,
                              int numTilesY = 0, byte[] tilePaletteRows = null)
        {
            // The tile maps (NSC / ISC) files for minimaps are always arranged a particular way - 0, 1, 2...15, 32 for 128 x 128
            Bitmap bmp = new Bitmap(filename);

            Color[] palette = bmp.Palette.Entries.ToArray <Color>();
            if (palette.Length > 256)
            {
                MessageBox.Show("Too many colours\n\nYou must import an indexed bitmap with a maximum of 256 colours.");
                return;
            }

            // Write new palette
            m_PalFile = Program.m_ROM.GetFileFromName(txtSelNCL.Text);
            m_PalFile.Clear();
            for (int i = 0; i < palette.Length; i++)
            {
                // Colour in BGR15 format (16 bits) written to every even address 0,2,4...
                m_PalFile.Write16((uint)i * 2, (ushort)(Helper.ColorToBGR15(palette[i])));
            }
            // Pad the palette to a multiple of 16 colours
            byte nColourSlots = (byte)((palette.Length % 16 != 0) ? ((palette.Length + 16) & ~15) : palette.Length);

            for (int i = palette.Length; i < nColourSlots; i++)
            {
                m_PalFile.Write16((uint)i * 2, 0);
            }

            m_PalFile.SaveChanges();

            // Fill current tmapfiles to use full mapsize x mapsize
            if (m_IsUsingTileMap)
            {
                m_TileMapFile = Program.m_ROM.GetFileFromName(txtSelNSC.Text);
                m_TileMapFile.Clear();
                sizeX = bmp.Width;
                sizeY = bmp.Height;
                uint addr    = 0;
                int  curTile = 0;
                int  row     = (int)(sizeX / 8);

                for (int my = 0; my < sizeY; my += 8)
                {
                    for (int mx = 0; mx < sizeX; mx += 8)
                    {
                        m_TileMapFile.Write16(addr, (ushort)curTile);
                        curTile++;
                        addr += 2;
                    }
                }
                if (chkNSCDcmp.Checked)
                {
                    m_TileMapFile.ForceCompression();
                }
                m_TileMapFile.SaveChanges();
            }// End If usingTMap

            //Check to see if there's already an identical tile and if so, change the current value to that
            //Works, but not if you want to keep existing data eg. multiple maps

            //List<List<byte>> tiles = new List<List<byte>>();
            //List<byte> curTilePal = new List<byte>();
            //uint tileoffset = 0;
            //for (int my = 0; my < sizeY; my += 8)
            //{
            //    for (int mx = 0; mx < sizeX; mx += 8)
            //    {
            //        ushort tilecrap = tmapfile.Read16(tileoffset);
            //        uint tilenum = (uint)(tilecrap & 0x03FF);

            //        curTilePal = new List<byte>();
            //        for (int ty = 0; ty < 8; ty++)
            //        {
            //            for (int tx = 0; tx < 8; tx++)
            //            {
            //                uint totaloffset = (uint)(tilenum * 64 + ty * 8 + tx);//Position of current pixel's entry
            //                curTilePal.Add((byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty))));
            //            }
            //        }

            //        tiles.Add(curTilePal);

            //        if (posInList(tiles, curTilePal) != -1)
            //        {
            //            tmapfile.Write16(tileoffset, (ushort)(posInList(tiles, curTilePal)));
            //        }

            //        tileoffset += 2;
            //    }
            //}

            //Write the new image to file
            m_TileSetFile = Program.m_ROM.GetFileFromName(txtSelNCG.Text);
            m_TileSetFile.Clear();
            uint tileoffset = 0;
            uint tileNum    = 0;

            for (int my = 0; my < sizeY; my += 8)
            {
                for (int mx = 0; mx < sizeX; mx += 8)
                {
                    for (int ty = 0; ty < 8; ty++)
                    {
                        for (int tx = 0; tx < 8; tx++)
                        {
                            if (bpp == 8)
                            {
                                uint totaloffset = (uint)(tileNum * 64 + ty * 8 + tx);//Position of current pixel's entry
                                byte palentry    = (byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty)));
                                m_TileSetFile.Write8(totaloffset, (byte)(palentry));
                            }
                            else if (bpp == 4)
                            {
                                float totaloffset = (float)((float)(tileNum * 64 + ty * 8 + tx) / 2f);//Address of current pixel
                                byte  palentry    = (byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty)));

                                int  currentTileIndex    = (int)tileNum;
                                byte currentTileRowIndex = tilePaletteRows[currentTileIndex];

                                byte rowStartColourOffset = (byte)(16 * currentTileRowIndex);
                                byte rowEndColourOffset   = (byte)(16 * (currentTileRowIndex + 1) - 1);

                                if (palentry < rowStartColourOffset || palentry > rowEndColourOffset) // Referencing colour outisde its row
                                {
                                    Color referencedColour = Helper.BGR15ToColor(m_PalFile.Read16((uint)(palentry * 2)));

                                    // Find the same colour in the correct row and set the current pixel to reference that instead
                                    for (int col = rowStartColourOffset; col < rowEndColourOffset; col++)
                                    {
                                        uint offset = (uint)(col * 2);

                                        if (offset >= m_PalFile.m_Data.Length)
                                        {
                                            break;
                                        }

                                        Color currentColour = Helper.BGR15ToColor(m_PalFile.Read16(offset));
                                        if (currentColour.Equals(referencedColour))
                                        {
                                            palentry = (byte)col;
                                            break;
                                        }
                                    }
                                }

                                if (totaloffset % 1 == 0)
                                {
                                    // Right 4 bits
                                    m_TileSetFile.Write8((uint)totaloffset, (byte)palentry);
                                    //(byte)((tsetfile.Read8((uint)totaloffset) & 0xF0) | palentry));
                                }
                                else
                                {
                                    // Left 4 bits
                                    m_TileSetFile.Write8((uint)totaloffset, (byte)((palentry << 4) |
                                                                                   (m_TileSetFile.Read8((uint)totaloffset) & 0x0F)));
                                }
                            }
                        }
                    }

                    tileoffset += 2;
                    tileNum++;
                }
            }

            if (chkNCGDcmp.Checked)
            {
                m_TileSetFile.ForceCompression();
            }
            m_TileSetFile.SaveChanges();

            // If it's a minimap that's being replaced, fill the tile maps to allow for multiple maps
            // and ensure the image's displayed at the right size since minimap sizes are hard-coded,
            // they are not based on the size of the imported image.
            if (replaceMinimap)
            {
                try
                {
                    if (chk128.Checked)
                    {
                        FillMinimapTiles(128);
                    }
                    else if (chk256.Checked)
                    {
                        FillMinimapTiles(256);
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message + ex.Source + ex.StackTrace); }
            }

            m_SizeX = sizeX;
            m_SizeY = sizeY;
        }
예제 #4
0
        public void ImportBMP(string filename, int bpp, int sizeX, int sizeY, bool replaceMinimap = false, int numTilesX = 0, 
            int numTilesY = 0, byte[] tilePaletteRows = null)
        {
            // The tile maps (NSC / ISC) files for minimaps are always arranged a particular way - 0, 1, 2...15, 32 for 128 x 128
            Bitmap bmp = new Bitmap(filename);

            Color[] palette = bmp.Palette.Entries.ToArray<Color>();
            if (palette.Length > 256)
            {
                MessageBox.Show("Too many colours\n\n" +
                    "You must import an indexed bitmap with 256 colours or fewer.");
                return;
            }

            //Write new palette
            m_PalFile = Program.m_ROM.GetFileFromName(txtSelNCL.Text);
            m_PalFile.Clear();
            for (int i = 0; i < palette.Length; i++)
            {
                //Colour in BGR15 format (16 bits) written to every even address 0,2,4...
                m_PalFile.Write16((uint)i * 2, (ushort)(Helper.ColorToBGR15(palette[i])));
            }
            for (int i = palette.Length; i < 256; i++)
                m_PalFile.Write16((uint)i * 2, 0);

            m_PalFile.SaveChanges();

            // Fill current tmapfiles to use full mapsize x mapsize
            if (m_IsUsingTileMap)
            {
                m_TileMapFile = Program.m_ROM.GetFileFromName(txtSelNSC.Text);
                m_TileMapFile.Clear();
                sizeX = bmp.Width;
                sizeY = bmp.Height;
                uint addr = 0;
                int curTile = 0;
                int row = (int)(sizeX / 8);

                for (int my = 0; my < sizeY; my += 8)
                {
                    for (int mx = 0; mx < sizeX; mx += 8)
                    {
                        m_TileMapFile.Write16(addr, (ushort)curTile);
                        curTile++;
                        addr += 2;
                    }
                }
                if (chkNSCDcmp.Checked)
                    m_TileMapFile.ForceCompression();
                m_TileMapFile.SaveChanges();
            }// End If usingTMap

            //Check to see if there's already an identical tile and if so, change the current value to that
            //Works, but not if you want to keep existing data eg. multiple maps

            //List<List<byte>> tiles = new List<List<byte>>();
            //List<byte> curTilePal = new List<byte>();
            //uint tileoffset = 0;
            //for (int my = 0; my < sizeY; my += 8)
            //{
            //    for (int mx = 0; mx < sizeX; mx += 8)
            //    {
            //        ushort tilecrap = tmapfile.Read16(tileoffset);
            //        uint tilenum = (uint)(tilecrap & 0x03FF);

            //        curTilePal = new List<byte>();
            //        for (int ty = 0; ty < 8; ty++)
            //        {
            //            for (int tx = 0; tx < 8; tx++)
            //            {
            //                uint totaloffset = (uint)(tilenum * 64 + ty * 8 + tx);//Position of current pixel's entry
            //                curTilePal.Add((byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty))));
            //            }
            //        }

            //        tiles.Add(curTilePal);

            //        if (posInList(tiles, curTilePal) != -1)
            //        {
            //            tmapfile.Write16(tileoffset, (ushort)(posInList(tiles, curTilePal)));
            //        }

            //        tileoffset += 2;
            //    }
            //}

            //Write the new image to file
            m_TileSetFile = Program.m_ROM.GetFileFromName(txtSelNCG.Text);
            m_TileSetFile.Clear();
            uint tileoffset = 0;
            uint tileNum = 0;
            for (int my = 0; my < sizeY; my += 8)
            {
                for (int mx = 0; mx < sizeX; mx += 8)
                {
                    for (int ty = 0; ty < 8; ty++)
                    {
                        for (int tx = 0; tx < 8; tx++)
                        {
                            if (bpp == 8)
                            {
                                uint totaloffset = (uint)(tileNum * 64 + ty * 8 + tx);//Position of current pixel's entry
                                byte palentry = (byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty)));
                                m_TileSetFile.Write8(totaloffset, (byte)(palentry));
                            }
                            else if (bpp == 4)
                            {
                                float totaloffset = (float)((float)(tileNum * 64 + ty * 8 + tx) / 2f);//Address of current pixel
                                byte palentry = (byte)(Array.IndexOf(palette, bmp.GetPixel(mx + tx, my + ty)));

                                int currentTileIndex = (int)tileNum;
                                byte currentTileRowIndex = tilePaletteRows[currentTileIndex];

                                byte rowStartColourOffset = (byte)(16 * currentTileRowIndex);
                                byte rowEndColourOffset = (byte)(16 * (currentTileRowIndex + 1) - 1);

                                if (palentry < rowStartColourOffset || palentry > rowEndColourOffset) // Referencing colour outisde its row
                                {
                                    Color referencedColour = Helper.BGR15ToColor(m_PalFile.Read16((uint)(palentry * 2)));

                                    // Find the same colour in the correct row and set the current pixel to reference that instead
                                    for (int col = rowStartColourOffset; col < rowEndColourOffset; col++)
                                    {
                                        uint offset = (uint)(col * 2);

                                        if (offset >= m_PalFile.m_Data.Length) break;

                                        Color currentColour = Helper.BGR15ToColor(m_PalFile.Read16(offset));
                                        if (currentColour.Equals(referencedColour))
                                        {
                                            palentry = (byte)col;
                                            break;
                                        }
                                    }
                                }

                                if (totaloffset % 1 == 0)
                                {
                                    // Right 4 bits
                                    m_TileSetFile.Write8((uint)totaloffset, (byte)palentry);
                                    //(byte)((tsetfile.Read8((uint)totaloffset) & 0xF0) | palentry));
                                }
                                else
                                {
                                    // Left 4 bits
                                    m_TileSetFile.Write8((uint)totaloffset, (byte)((palentry << 4) |
                                        (m_TileSetFile.Read8((uint)totaloffset) & 0x0F)));
                                }
                            }
                        }
                    }

                    tileoffset += 2;
                    tileNum++;
                }
            }

            if (chkNCGDcmp.Checked)
                m_TileSetFile.ForceCompression();
            m_TileSetFile.SaveChanges();

            // If it's a minimap that's being replaced, fill the tile maps to allow for multiple maps
            // and ensure the image's displayed at the right size as you can't change the size of
            // a level's minimap - it seems to be hardcoded somewhere (in level header?)
            if (replaceMinimap)
            {
                try
                {
                    if (chk128.Checked)
                        FillMinimapTiles(128);
                    else if (chk256.Checked)
                        FillMinimapTiles(256);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message + ex.Source + ex.StackTrace); }
            }
        }
예제 #5
0
        public void SwitchBackground(int swapped)
        {
            m_PalFile = Program.m_ROM.GetFileFromName(txtSelNCL.Text);
            //The background colour is the first colour stored in the palette
            ushort first = m_PalFile.Read16((uint)0);//Read the first colour in the palette file
            ushort swappedColour = m_PalFile.Read16((uint)(swapped * 2));//Read the colour to be swapped
            //Colour in BGR15 format (16 bits) written to every even address 0,2,4...
            m_PalFile.Write16((uint)0, swappedColour);//Write new background colour to first entry
            m_PalFile.Write16((uint)(swapped * 2), first);//Write the previously first colour to the colour being swapped

            m_PalFile.SaveChanges();

            //Swap all palette file entries for the swapped colours in the graphic file
            m_TileSetFile = Program.m_ROM.GetFileFromName(txtSelNCG.Text);
            if (chkNCGDcmp.Checked)
                m_TileSetFile.ForceDecompression();
            uint tileoffset = 0, tilenum = 0;
            ushort tilecrap = 0;
            for (int my = 0; my < m_SizeY; my += 8)
            {
                for (int mx = 0; mx < m_SizeX; mx += 8)
                {
                    if (m_IsUsingTileMap)
                    {
                        tilecrap = m_TileMapFile.Read16(tileoffset);
                        tilenum = (uint)(tilecrap & 0x03FF);
                    }

                    for (int ty = 0; ty < 8; ty++)
                    {
                        for (int tx = 0; tx < 8; tx++)
                        {
                            if (m_BPP == 8)
                            {
                                uint totaloffset = (uint)(tilenum * 64 + ty * 8 + tx);//Position of current pixel's entry
                                byte palentry = m_TileSetFile.Read8(totaloffset);
                                if (palentry == 0)//If the current pixel points to first colour in palette,
                                    m_TileSetFile.Write8(totaloffset, (byte)(swapped));//point it to the swapped colour
                                if (palentry == (byte)swapped)//If the current pixel points to the swapped colour in palette,
                                    m_TileSetFile.Write8(totaloffset, (byte)0);//point it to the first colour
                            }
                            else if (m_BPP == 4)
                            {
                                float totaloffset = (float)((float)(tilenum * 64 + ty * 8 + tx) / 2f);//Address of current pixel
                                byte palentry = 0;
                                if (totaloffset % 1 == 0)
                                {
                                    // Right 4 bits
                                    palentry = m_TileSetFile.Read8((uint)totaloffset);//Offset of current pixel's entry in palette file
                                    palentry = (byte)(palentry & 0x0F);// Get 4 right bits
                                    if (palentry == 0)//If the current pixel points to first colour in palette,
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((m_TileSetFile.Read8((uint)totaloffset) & 0xF0) | swapped));//point it to the swapped colour
                                    if (palentry == (byte)swapped)//If the current pixel points to the swapped colour in palette,
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((m_TileSetFile.Read8((uint)totaloffset) & 0xF0) | 0));//point it to the first colour
                                }
                                else
                                {
                                    // Left 4 bits
                                    palentry = m_TileSetFile.Read8((uint)totaloffset);//Offset of current pixel's entry in palette file
                                    palentry = (byte)(palentry >> 4);
                                    if (palentry == 0)//If the current pixel points to first colour in palette,
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)((swapped << 4) | (m_TileSetFile.Read8((uint)totaloffset) & 0x0F)));//point it to the swapped colour
                                    if (palentry == (byte)swapped)//If the current pixel points to the swapped colour in palette,
                                        m_TileSetFile.Write8((uint)totaloffset, (byte)(0 | (m_TileSetFile.Read8((uint)totaloffset) & 0x0F)));//point it to the first colour
                                }
                            }
                        }
                    }

                    tileoffset += 2;
                    if (!m_IsUsingTileMap)
                        tilenum++;
                }
            }

            if (chkNCGDcmp.Checked)
                m_TileSetFile.ForceCompression();
            m_TileSetFile.SaveChanges();

            RedrawMinimap(m_IsUsingTileMap, m_SizeX, m_SizeY, m_BPP, m_PaletteRow);
        }