private void patchExport_Click(object sender, EventArgs e) { //output to show to the user bool differentRomsWarning = false; // tells if we have shown the warning int fileCount = 0; //load the original rom MessageBox.Show(LanguageManager.Get("Patch", "SelectROM"), LanguageManager.Get("Patch", "Export"), MessageBoxButtons.OK, MessageBoxIcon.Information); if (openROMDialog.ShowDialog() == DialogResult.Cancel) { return; } NitroROMFilesystem origROM = new NitroROMFilesystem(openROMDialog.FileName); //open the output patch MessageBox.Show(LanguageManager.Get("Patch", "SelectLocation"), LanguageManager.Get("Patch", "Export"), MessageBoxButtons.OK, MessageBoxIcon.Information); if (savePatchDialog.ShowDialog() == DialogResult.Cancel) { return; } FileStream fs = new FileStream(savePatchDialog.FileName, FileMode.Create, FileAccess.Write, FileShare.None); BinaryWriter bw = new BinaryWriter(fs); bw.Write(patchHeader); //DO THE PATCH!! ProgressWindow progress = new ProgressWindow(LanguageManager.Get("Patch", "ExportProgressTitle")); progress.Show(); progress.SetMax(ROM.FS.allFiles.Count); int progVal = 0; MessageBox.Show(LanguageManager.Get("Patch", "StartingPatch"), LanguageManager.Get("Patch", "Export"), MessageBoxButtons.OK, MessageBoxIcon.Information); foreach (NSMBe5.DSFileSystem.File f in ROM.FS.allFiles) { if (f.isSystemFile) { continue; } Console.Out.WriteLine("Checking " + f.name); progress.SetCurrentAction(string.Format(LanguageManager.Get("Patch", "ComparingFile"), f.name)); NSMBe5.DSFileSystem.File orig = origROM.getFileByName(f.name); //check same version if (orig == null) { new ErrorMSGBox("", "", "In this case it is recommended that you continue.", "This ROM has more files than the original clean ROM or a file was renamed!\n\nPlease make an XDelta patch instead.\n\nExport will end now.").ShowDialog(); bw.Write((byte)0); bw.Close(); origROM.close(); progress.SetCurrentAction(""); progress.WriteLine(string.Format(LanguageManager.Get("Patch", "ExportReady"), fileCount)); return; } else if (!differentRomsWarning && f.id != orig.id) { if (MessageBox.Show(LanguageManager.Get("Patch", "ExportDiffVersions"), LanguageManager.Get("General", "Warning"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { differentRomsWarning = true; } else { fs.Close(); return; } } byte[] oldFile = orig.getContents(); byte[] newFile = f.getContents(); if (!arrayEqual(oldFile, newFile)) { //include file in patch string fileName = orig.name; Console.Out.WriteLine("Including: " + fileName); progress.WriteLine(string.Format(LanguageManager.Get("Patch", "IncludedFile"), fileName)); fileCount++; bw.Write((byte)1); bw.Write(fileName); bw.Write((ushort)f.id); bw.Write((uint)newFile.Length); bw.Write(newFile, 0, newFile.Length); } progress.setValue(++progVal); } bw.Write((byte)0); bw.Close(); origROM.close(); progress.SetCurrentAction(""); progress.WriteLine(string.Format(LanguageManager.Get("Patch", "ExportReady"), fileCount)); }
private void patchImport_Click(object sender, EventArgs e) { //output to show to the user bool differentRomsWarning = false; // tells if we have shown the warning int fileCount = 0; //open the input patch if (openPatchDialog.ShowDialog() == DialogResult.Cancel) { return; } FileStream fs = new FileStream(openPatchDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader br = new BinaryReader(fs); string header = br.ReadString(); if (!(header == patchHeader || header == oldPatchHeader)) { MessageBox.Show( LanguageManager.Get("Patch", "InvalidFile"), LanguageManager.Get("Patch", "Unreadable"), MessageBoxButtons.OK, MessageBoxIcon.Error); br.Close(); return; } ProgressWindow progress = new ProgressWindow(LanguageManager.Get("Patch", "ImportProgressTitle")); progress.Show(); byte filestartByte = br.ReadByte(); try { while (filestartByte == 1) { string fileName = br.ReadString(); progress.WriteLine(string.Format(LanguageManager.Get("Patch", "ReplacingFile"), fileName)); ushort origFileID = br.ReadUInt16(); NSMBe5.DSFileSystem.File f = ROM.FS.getFileByName(fileName); uint length = br.ReadUInt32(); byte[] newFile = new byte[length]; br.Read(newFile, 0, (int)length); filestartByte = br.ReadByte(); if (f != null) { ushort fileID = (ushort)f.id; if (!differentRomsWarning && origFileID != fileID) { MessageBox.Show(LanguageManager.Get("Patch", "ImportDiffVersions"), LanguageManager.Get("General", "Warning"), MessageBoxButtons.OK, MessageBoxIcon.Warning); differentRomsWarning = true; } if (!f.isSystemFile) { Console.Out.WriteLine("Replace " + fileName); f.beginEdit(this); f.replace(newFile, this); f.endEdit(this); } fileCount++; } } } catch (AlreadyEditingException) { MessageBox.Show(string.Format(LanguageManager.Get("Patch", "Error"), fileCount), LanguageManager.Get("General", "Completed"), MessageBoxButtons.OK, MessageBoxIcon.Error); } br.Close(); MessageBox.Show(string.Format(LanguageManager.Get("Patch", "ImportReady"), fileCount), LanguageManager.Get("General", "Completed"), MessageBoxButtons.OK, MessageBoxIcon.Information); // progress.Close(); }
public ImageTiler(Bitmap b, Size bitmapSize, Size tilemapSize, int mergeDiffPercentage) { ProgressWindow p = new ProgressWindow(LanguageManager.Get("BgImport", "Importing")); p.Show(); diffSize = mergeDiffPercentage / 100f; numberOfCharacters = (bitmapSize.Width * bitmapSize.Height) / 64; widthTileCount = tilemapSize.Width / 8; heightTileCount = tilemapSize.Height / 8; tileCount = widthTileCount * heightTileCount; p.SetMax(tileCount); tileMap = new int[widthTileCount, heightTileCount]; tileDiffs = new float[tileCount, tileCount]; tiles = new Tile[tileCount]; diffs = new List <TileDiff>(); //LOAD TILES p.WriteLine("1/5: Loading tiles..."); int tileNum = 0; for (int xt = 0; xt < widthTileCount; xt++) { for (int yt = 0; yt < heightTileCount; yt++) { // Console.Out.WriteLine("Tile " + xt + " " + yt + ", " + tileNum); tiles[tileNum] = new Tile(b, xt * 8, yt * 8); tileMap[xt, yt] = tileNum; tileNum++; //p.setValue(xt * 64 + yt); } // Console.Out.WriteLine(xt); } p.setValue(0); p.SetMax(tileCount); p.WriteLine("2/5: Computing tile differences..."); for (int xt = 0; xt < tileCount; xt++) { p.setValue(xt); if (tiles[xt] == null) { continue; } for (int yt = 0; yt < xt; yt++) { if (tiles[yt] == null) { continue; } float diff = tiles[xt].difference(tiles[yt]); if (diff < diffSize) { mergeTiles(xt, yt); } else { TileDiff td = new TileDiff(); td.diff = diff; td.t1 = xt; td.t2 = yt; diffs.Add(td); } } } // p.WriteLine("Tiles merged in first pass: "******" of " + 64 * 64); p.WriteLine("3/5: Sorting tiles..."); diffs.Sort(); p.WriteLine("4/5: Merging tiles..."); //REDUCE TILE COUNT int used = countUsedTiles(); int mustRemove = used - numberOfCharacters; if (used > numberOfCharacters) { p.setValue(0); p.SetMax(mustRemove); } List <TileDiff> .Enumerator en = diffs.GetEnumerator(); while (used > numberOfCharacters) { en.MoveNext(); TileDiff td = en.Current; int t1 = td.t1; int t2 = td.t2; if (tiles[t1] == null) { continue; } if (tiles[t2] == null) { continue; } if (t1 == t2) { throw new Exception("Should never happen"); } mergeTiles(t1, t2); used = countUsedTiles(); p.setValue(mustRemove - used + numberOfCharacters); } p.WriteLine("5/5: Buiding tile map..."); /* * //DEBUG, DEBUG... * * for (int yt = 0; yt < 64; yt++) * { * for (int xt = 0; xt < 64; xt++) * Console.Out.Write(tileMap[xt, yt].ToString("X2") + " "); * Console.Out.WriteLine(); * } * * Bitmap bb = new Bitmap(512, 512, PixelFormat.Format32bppArgb); * for (int xt = 0; xt < 64; xt++) * for (int yt = 0; yt < 64; yt++) * { * for (int x = 0; x < 8; x++) * for (int y = 0; y < 8; y++) * { * Color c = tiles[tileMap[xt, yt]].data[x, y]; * // Console.Out.WriteLine(c); * bb.SetPixel(xt * 8 + x, yt * 8 + y, c); * } * } * * bb.Save("C:\\image2.png"); * new ImagePreviewer(bb).Show();*/ //COMPACTIFY TILES AND MAKE THE TILE BUFFER!!! tileBuffer = new Bitmap(countUsedTiles() * 8, 8, PixelFormat.Format32bppArgb); int[] newTileNums = new int[tileCount]; int nt = 0; for (int t = 0; t < tileCount; t++) { if (tiles[t] != null) { newTileNums[t] = nt; for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { tileBuffer.SetPixel(x + nt * 8, y, tiles[t].data[x, y]); } } nt++; } } // new ImagePreviewer(tileBuffer).Show(); for (int xt = 0; xt < widthTileCount; xt++) { for (int yt = 0; yt < heightTileCount; yt++) { tileMap[xt, yt] = newTileNums[tileMap[xt, yt]]; } } p.WriteLine("Done! You can close this window now."); }