public NesGame(string gamesDirectory, string nesFileName) { var nesFile = new NesFile(nesFileName); nesFile.CorrectRom(); if (!supportedMappers.Contains(nesFile.Mapper)) { throw new Exception(string.Format(Resources.MapperNotSupported, Path.GetFileName(nesFileName), nesFile.Mapper)); } Code = string.Format("CLV-H-{0}{1}{2}{3}{4}", (char)('A' + (nesFile.CRC32 % 26)), (char)('A' + (nesFile.CRC32 >> 5) % 26), (char)('A' + ((nesFile.CRC32 >> 10) % 26)), (char)('A' + ((nesFile.CRC32 >> 15) % 26)), (char)('A' + ((nesFile.CRC32 >> 20) % 26))); GamePath = Path.Combine(gamesDirectory, Code); ConfigPath = Path.Combine(GamePath, Code + ".desktop"); Directory.CreateDirectory(GamePath); NesPath = Path.Combine(GamePath, Code + ".nes"); nesFile.Save(NesPath); Name = Path.GetFileNameWithoutExtension(nesFileName); Name = Regex.Replace(Name, @" ?\(.*?\)", string.Empty).Trim(); Name = Regex.Replace(Name, @" ?\[.*?\]", string.Empty).Trim(); Name = Name.Replace(", The", "").Replace("_", " ").Replace(" ", " ").Trim(); Players = 1; ReleaseDate = "1983-07-15"; Publisher = "Nintendo"; Args = "--guest-overscan-dimensions 0,0,9,3 --initial-fadein-durations 3,2 --volume 75 --enable-armet"; IconPath = Path.Combine(GamePath, Code + ".png"); SmallIconPath = Path.Combine(GamePath, Code + "_small.png"); SetImage(Resources.blank); Save(); }
public NesGame(string gamesDirectory, string nesFileName, bool ignoreMapper = false) { if (!Path.GetExtension(nesFileName).ToLower().Equals(".fds")) { var nesFile = new NesFile(nesFileName); nesFile.CorrectRom(); if (!supportedMappers.Contains(nesFile.Mapper) && !ignoreMapper) { throw new UnsupportedMapperException(nesFile); } var crc32 = nesFile.CRC32; Code = string.Format("CLV-H-{0}{1}{2}{3}{4}", (char)('A' + (crc32 % 26)), (char)('A' + (crc32 >> 5) % 26), (char)('A' + ((crc32 >> 10) % 26)), (char)('A' + ((crc32 >> 15) % 26)), (char)('A' + ((crc32 >> 20) % 26))); GamePath = Path.Combine(gamesDirectory, Code); ConfigPath = Path.Combine(GamePath, Code + ".desktop"); Directory.CreateDirectory(GamePath); NesPath = Path.Combine(GamePath, Code + ".nes"); nesFile.Save(NesPath); } else { var fdsData = File.ReadAllBytes(nesFileName); var crc32 = CRC32(fdsData); Code = string.Format("CLV-H-{0}{1}{2}{3}{4}", (char)('A' + (crc32 % 26)), (char)('A' + (crc32 >> 5) % 26), (char)('A' + ((crc32 >> 10) % 26)), (char)('A' + ((crc32 >> 15) % 26)), (char)('A' + ((crc32 >> 20) % 26))); GamePath = Path.Combine(gamesDirectory, Code); ConfigPath = Path.Combine(GamePath, Code + ".desktop"); Directory.CreateDirectory(GamePath); NesPath = Path.Combine(GamePath, Code + ".nes"); File.WriteAllBytes(NesPath, fdsData); } Name = Path.GetFileNameWithoutExtension(nesFileName); Name = Regex.Replace(Name, @" ?\(.*?\)", string.Empty).Trim(); Name = Regex.Replace(Name, @" ?\[.*?\]", string.Empty).Trim(); Name = Name.Replace(", The", "").Replace("_", " ").Replace(" ", " ").Trim(); Players = 1; ReleaseDate = "1983-07-15"; Publisher = "Nintendo"; Args = "--guest-overscan-dimensions 0,0,9,3 --initial-fadein-durations 3,2 --volume 75 --enable-armet"; IconPath = Path.Combine(GamePath, Code + ".png"); SmallIconPath = Path.Combine(GamePath, Code + "_small.png"); SetImage(Resources.blank); Save(); }
public Game(string fileName, string menuName = null, Dictionary <uint, GameFix> fixes = null) { // Separators if (fileName == "-") { MenuName = (string.IsNullOrWhiteSpace(menuName) || menuName == "-") ? "" : menuName; FileName = ""; Flags |= GameFlags.Separator; } else { Console.WriteLine("Loading {0}...", Path.GetFileName(fileName)); FileName = fileName; if (string.IsNullOrWhiteSpace(menuName)) { // Menu name based on filename MenuName = Regex.Replace(Path.GetFileNameWithoutExtension(fileName), @"( ?\[.*?\])|( \(.\))", string.Empty).Replace("_", " ").ToUpper().Replace(", THE", "").Trim(); } else { MenuName = menuName.Trim(); if (MenuName == "?") { Flags |= GameFlags.Hidden; } } // Strip long names if (MenuName.Length > 28) { MenuName = MenuName.Substring(0, 25).Trim() + "..."; } uint crc; try { var nesFile = new NesFile(fileName); var fixResult = nesFile.CorrectRom(); if (fixResult != 0) { Console.WriteLine(" Invalid header. Fix: " + fixResult); } PRG = nesFile.PRG; PrgSize = (uint)nesFile.PRG.Count(); CHR = nesFile.CHR; ChrSize = (uint)nesFile.CHR.Count(); Battery = nesFile.Battery; Mapper = $"{nesFile.Mapper:D3}" + ((nesFile.Submapper > 0) ? $":{nesFile.Submapper}" : ""); Mirroring = nesFile.Mirroring; ContainerType = NesContainerType.iNES; if (nesFile.Trainer != null && nesFile.Trainer.Count() > 0) { throw new NotImplementedException(string.Format("{0} - trained games are not supported yet", Path.GetFileName(fileName))); } if (nesFile.Version == NesFile.iNesVersion.NES20) { PrgRamSize = nesFile.PrgRamSize + nesFile.PrgNvRamSize; ChrRamSize = nesFile.ChrRamSize + nesFile.ChrNvRamSize; } crc = nesFile.CalculateCRC32(); } catch (InvalidDataException) { var unifFile = new UnifFile(fileName); PRG = unifFile.Fields.Where(k => k.Key.StartsWith("PRG")).OrderBy(k => k.Key).SelectMany(i => i.Value); PrgSize = (uint)PRG.Count(); CHR = unifFile.Fields.Where(k => k.Key.StartsWith("CHR")).OrderBy(k => k.Key).SelectMany(i => i.Value); ChrSize = (uint)CHR.Count(); Battery = unifFile.Battery; var mapper = unifFile.Mapper; if (mapper.StartsWith("NES-") || mapper.StartsWith("UNL-") || mapper.StartsWith("HVC-") || mapper.StartsWith("BTL-") || mapper.StartsWith("BMC-")) { mapper = mapper.Substring(4); } Mapper = mapper; Mirroring = unifFile.Mirroring; ContainerType = NesContainerType.UNIF; crc = unifFile.CalculateCRC32(); } // Check for fixes database if (fixes != null) { GameFix fix = null; if (fixes.TryGetValue(crc, out fix)) { if (fix.PrgRamSize.HasValue) { PrgRamSize = fix.PrgRamSize * 1024; } if (fix.ChrRamSize.HasValue) { ChrRamSize = fix.ChrRamSize * 1024; } if (fix.Battery.HasValue) { Battery = fix.Battery.Value; } if (fix.WillNotWorkOnPal) { Flags |= GameFlags.WillNotWorkOnPal; } if (fix.WillNotWorkOnNtsc) { Flags |= GameFlags.WillNotWorkOnNtsc; } if (fix.WillNotWorkOnDendy) { Flags |= GameFlags.WillNotWorkOnDendy; } if (fix.WillNotWorkOnNewFamiclone) { Flags |= GameFlags.WillNotWorkOnNewFamiclone; } } } // External NTRAM is not supported on new famiclones if (Mirroring == NesFile.MirroringType.FourScreenVram) { Flags |= GameFlags.WillNotWorkOnNewFamiclone; } // Check for round sizes if (PrgSize > 0) { uint roundSize = 1; while (roundSize < PrgSize) { roundSize <<= 1; } if (roundSize > PrgSize) { var newPrg = new byte[roundSize]; for (uint i = PrgSize; i < roundSize; i++) { newPrg[i] = 0xFF; } Array.Copy(PRG.ToArray(), newPrg, PrgSize); PRG = newPrg; PrgSize = roundSize; } } if (ChrSize > 0) { uint roundSize = 1; while (roundSize < ChrSize) { roundSize <<= 1; } if (roundSize > ChrSize) { var newChr = new byte[roundSize]; for (uint i = ChrSize; i < roundSize; i++) { newChr[i] = 0xFF; } Array.Copy(CHR.ToArray(), newChr, ChrSize); CHR = newChr; ChrSize = roundSize; } } } }
public static bool Patch(string inputFileName, ref byte[] rawRomData, ref char prefix, ref string application, ref string outputFileName, ref string args, ref Image cover, ref uint crc32) { // Try to patch before mapper check, maybe it will patch mapper FindPatch(ref rawRomData, inputFileName, crc32); NesFile nesFile; try { nesFile = new NesFile(rawRomData); } catch { application = "/bin/nes"; return(true); } nesFile.CorrectRom(); crc32 = nesFile.CRC32; if (ConfigIni.ConsoleType == MainForm.ConsoleType.NES || ConfigIni.ConsoleType == MainForm.ConsoleType.Famicom) { application = "/bin/clover-kachikachi-wr"; } else { application = "/bin/nes"; } //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)) { if (IgnoreMapper != false) { var r = WorkerForm.MessageBoxFromThread(ParentForm, string.Format(Resources.MapperNotSupported, System.IO.Path.GetFileName(inputFileName), nesFile.Mapper), Resources.AreYouSure, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true); if (r == DialogResult.Abort) { IgnoreMapper = true; } if (r == DialogResult.Ignore) { return(false); } } else { return(false); } } if ((nesFile.Mirroring == NesFile.MirroringType.FourScreenVram) && (IgnoreMapper != true)) { var r = WorkerForm.MessageBoxFromThread(ParentForm, string.Format(Resources.FourScreenNotSupported, System.IO.Path.GetFileName(inputFileName)), Resources.AreYouSure, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, true); if (r == DialogResult.Abort) { IgnoreMapper = true; } if (r == DialogResult.No) { return(false); } } // TODO: Make trainer check. I think that the NES Mini doesn't support it. rawRomData = nesFile.GetRaw(); if (inputFileName.Contains("(J)")) { cover = Resources.blank_jp; } args = DefaultArgs; return(true); }