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(); }
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); }
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; }
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); } } }
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); }