public static NesMiniApplication ImportNes(string nesFileName, bool?ignoreMapper, ref bool?needPatch, NeedPatchDelegate needPatchCallback = null, Form parentForm = null, byte[] rawRomData = null) { NesFile nesFile; try { if (rawRomData != null) { nesFile = new NesFile(rawRomData); } else { nesFile = new NesFile(nesFileName); } } catch { return(NesMiniApplication.Import(nesFileName, rawRomData)); } nesFile.CorrectRom(); var crc32 = nesFile.CRC32; var code = GenerateCode(crc32, Prefix); var gamePath = Path.Combine(GamesDirectory, code); var nesPath = Path.Combine(gamePath, code + ".nes"); var patchesDirectory = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "patches"); Directory.CreateDirectory(patchesDirectory); Directory.CreateDirectory(gamePath); var patches = Directory.GetFiles(patchesDirectory, string.Format("{0:X8}*.ips", crc32), SearchOption.AllDirectories); if (patches.Length > 0 && needPatch != false) { if (needPatch == true || ((needPatchCallback != null) && needPatchCallback(parentForm, Path.GetFileName(nesFileName)))) { needPatch = true; var patch = patches[0]; if (rawRomData == null) { rawRomData = File.ReadAllBytes(nesFileName); } Debug.WriteLine(string.Format("Patching {0}", nesFileName)); IpsPatcher.Patch(patch, ref rawRomData); nesFile = new NesFile(rawRomData); } else { needPatch = false; } } if (nesFile.Mapper == 71) { nesFile.Mapper = 2; // games by Codemasters/Camerica - this is UNROM clone. One exception - Fire Hawk } if (nesFile.Mapper == 88) { nesFile.Mapper = 4; // Compatible with MMC3... sometimes } if (nesFile.Mapper == 95) { nesFile.Mapper = 4; // Compatible with MMC3 } if (nesFile.Mapper == 206) { nesFile.Mapper = 4; // Compatible with MMC3 } if (!supportedMappers.Contains(nesFile.Mapper) && (ignoreMapper != true)) { Directory.Delete(gamePath, true); if (ignoreMapper != false) { throw new UnsupportedMapperException(nesFile); } else { Debug.WriteLine(string.Format("Game {0} has mapper #{1}, skipped", nesFileName, nesFile.Mapper)); return(null); } } if ((nesFile.Mirroring == NesFile.MirroringType.FourScreenVram) && (ignoreMapper != true)) { Directory.Delete(gamePath, true); if (ignoreMapper != false) { throw new UnsupportedFourScreenException(nesFile); } else { Debug.WriteLine(string.Format("Game {0} has four-screen mirroring, skipped", nesFileName, nesFile.Mapper)); return(null); } } // TODO: Make trainer check. I think that the NES Mini doesn't support it. nesFile.Save(nesPath); var game = new NesGame(gamePath, true); game.Name = Path.GetFileNameWithoutExtension(nesFileName); if (game.Name.Contains("(J)")) { game.region = "Japan"; } game.TryAutofill(crc32); game.Name = Regex.Replace(game.Name, @" ?\(.*?\)", string.Empty).Trim(); game.Name = Regex.Replace(game.Name, @" ?\[.*?\]", string.Empty).Trim(); game.Name = game.Name.Replace("_", " ").Replace(" ", " "); game.FindCover(nesFileName, (game.region == "Japan") ? Resources.blank_jp : Resources.blank_nes, crc32); game.Args = DefaultArgs; game.Save(); return(game); }
public ICollection <NesMiniApplication> AddGames(string[] files, Form parentForm = null) { var apps = new List <NesMiniApplication>(); addedApplications = null; //bool NoForAllUnsupportedMappers = false; bool YesForAllUnsupportedMappers = false; YesForAllPatches = false; int count = 0; SetStatus(Resources.AddingGames); foreach (var file in files) { NesMiniApplication app = null; try { var fileName = file; var ext = Path.GetExtension(file).ToLower(); bool? needPatch = YesForAllPatches ? (bool?)true : null; byte[] rawData = null; if (ext == ".7z" || ext == ".zip" || ext == ".rar") { SevenZipExtractor.SetLibraryPath(Path.Combine(baseDirectory, IntPtr.Size == 8 ? @"tools\7z64.dll" : @"tools\7z.dll")); using (var szExtractor = new SevenZipExtractor(file)) { var filesInArchive = new List <string>(); var nesFilesInArchive = new List <string>(); foreach (var f in szExtractor.ArchiveFileNames) { var e = Path.GetExtension(f).ToLower(); if (e == ".nes" || e == ".fds" || e == ".unf" || e == ".unif") { nesFilesInArchive.Add(f); } filesInArchive.Add(f); } if (nesFilesInArchive.Count == 1) // Only one NES file { fileName = nesFilesInArchive[0]; } else if (nesFilesInArchive.Count > 1) // Many NES files, need to select { if (SelectFileFromThread(nesFilesInArchive.ToArray()) == DialogResult.OK) { fileName = selectedFile; } else { continue; } } else if (filesInArchive.Count == 1) // No NES files but only one another file { fileName = filesInArchive[0]; } else // Need to select { if (SelectFileFromThread(filesInArchive.ToArray()) == DialogResult.OK) { fileName = selectedFile; } else { continue; } } var o = new MemoryStream(); szExtractor.ExtractFile(fileName, o); rawData = new byte[o.Length]; o.Seek(0, SeekOrigin.Begin); o.Read(rawData, 0, (int)o.Length); } } if (Path.GetExtension(fileName).ToLower() == ".nes") { try { app = NesGame.Import(fileName, YesForAllUnsupportedMappers ? (bool?)true : null, ref needPatch, needPatchCallback, this, rawData); // Trying to import Game Genie codes var lGameGeniePath = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".xml"); if (File.Exists(lGameGeniePath)) { GameGenieDataBase lGameGenieDataBase = new GameGenieDataBase(app); lGameGenieDataBase.ImportCodes(lGameGeniePath, true); lGameGenieDataBase.Save(); } } catch (Exception ex) { if (ex is UnsupportedMapperException || ex is UnsupportedFourScreenException) { var r = MessageBoxFromThread(this, (ex is UnsupportedMapperException) ? string.Format(Resources.MapperNotSupported, Path.GetFileName(fileName), (ex as UnsupportedMapperException).ROM.Mapper) : string.Format(Resources.FourScreenNotSupported, Path.GetFileName(fileName)), Resources.AreYouSure, files.Length <= 1 ? MessageBoxButtons.YesNo : MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true); while (r == DialogResult.None) { Thread.Sleep(100); } if (r == DialogResult.Yes || r == DialogResult.Abort || r == DialogResult.Retry) { app = NesGame.Import(fileName, true, ref needPatch, needPatchCallback, this, rawData); } if (r == DialogResult.Abort) { YesForAllUnsupportedMappers = true; } } else { throw ex; } } } else { app = NesMiniApplication.Import(fileName, rawData); } ConfigIni.SelectedGames += ";" + app.Code; } catch (Exception ex) { if (ex is ThreadAbortException) { return(null); } Debug.WriteLine(ex.Message + ex.StackTrace); ShowError(ex, true); } if (app != null) { apps.Add(app); } SetProgress(++count, files.Length); } return(apps); // Added games/apps }