/// <summary> /// Gets IProgramInformation from a .ROM-format file's metadata, if it is available. /// </summary> /// <param name="rom">The ROM from which metadata-based information is retrieved.</param> /// <returns>IProgramInformation retrieved from the .ROM-format ROM.</returns> public static RomFileMetadataProgramInformation GetRomFileMetadata(this IRom rom) { RomFileMetadataProgramInformation programInfo = null; var romRom = Rom.AsSpecificRomType <RomFormatRom>(rom); if (romRom != null) { programInfo = new RomFileMetadataProgramInformation(rom); if (!programInfo.Metadata.Any()) { programInfo = null; } } return(programInfo); }
/// <summary> /// Gets the fully qualified path to the cached ROM file's configuration file, if applicable. /// </summary> /// <param name="rom">The ROM whose cached configuration file is requested.</param> /// <param name="romStagingAreaPath">The staging area directory for the ROM.</param> /// <returns>The fully qualified path to the cached ROM's configuration file. If the ROM does not /// have a configuration file, then <c>null</c> is returned.</returns> public static string GetCachedConfigFilePath(this IRom rom, string romStagingAreaPath) { // NOTE: BUG ? : There's a goofy thing in that files w/o a cfg use the bin path... why? string cachedConfigPath = null; if (!string.IsNullOrWhiteSpace(rom.ConfigPath) && !string.IsNullOrWhiteSpace(rom.RomPath) && (rom.RomPath != rom.ConfigPath)) { cachedConfigPath = System.IO.Path.Combine(romStagingAreaPath, System.IO.Path.GetFileName(rom.ConfigPath)); if (rom.IsUsingStockCfgFilePath()) { cachedConfigPath = Path.ChangeExtension(Path.Combine(romStagingAreaPath, Path.GetFileName(rom.RomPath)), ProgramFileKind.CfgFile.FileExtension()); } } return(cachedConfigPath); }
/// <summary> /// Gets IProgramInformation from a .BIN-format file's metadata, if it is available. /// </summary> /// <param name="rom">The ROM from which metadata-based information is retrieved.</param> /// <returns>IProgramInformation retrieved from the .BIN-format ROM's .cfg file.</returns> public static CfgFileMetadataProgramInformation GetBinFileMetadata(this IRom rom) { CfgFileMetadataProgramInformation programInfo = null; var binRom = Rom.AsSpecificRomType <BinFormatRom>(rom); if (binRom != null) { programInfo = new CfgFileMetadataProgramInformation(rom); if (!programInfo.Metadata.Any()) { programInfo = null; } } return(programInfo); }
private static IEnumerable <string> GetRomInfo(IRom rom) { lock (RomInfos) { var info = Enumerable.Empty <string>(); if (!string.IsNullOrEmpty(rom.RomPath)) { RomInfoData romInfo; if (RomInfos.TryGetValue(rom.RomPath, out romInfo)) { info = romInfo.Info; } } return(info); } }
/// <summary> /// Gets the fully qualified path to the expected output file produced by the conversion tool. /// </summary> /// <param name="rom">The ROM whose conversion output file is desired.</param> /// <param name="romStagingAreaPath">The staging area directory for the ROM.</param> /// <param name="programFileKind">Target program file kind.</param> /// <param name="includeOriginalFormat">If <c>true</c>, include the original ROM file format as part of the output file name.</param> /// <returns>The fully qualified path to the expected output file.</returns> public static string GetOutputFilePath(this IRom rom, string romStagingAreaPath, INTV.Core.Model.Program.ProgramFileKind programFileKind, bool includeOriginalFormat) { var cachedPath = rom.GetCachedRomFilePath(romStagingAreaPath); var extension = System.IO.Path.GetExtension(cachedPath); if (includeOriginalFormat) { var originalExtension = rom.Format.FileExtension(); var suffix = originalExtension.Replace('.', '_'); cachedPath = cachedPath + suffix + originalExtension; } cachedPath = System.IO.Path.ChangeExtension(cachedPath, extension); var path = System.IO.Path.ChangeExtension(cachedPath, programFileKind.FileExtension()); return(path); }
/// <summary> /// Gets the fully qualified path of the staging area directory for the ROM. /// </summary> /// <param name="rom">The ROM whose staging area is requested.</param> /// <param name="baseRomStagingArea">The base directory for the staging area.</param> /// <returns>The fully qualified path to the staging area.</returns> /// <remarks>The staging area directory will be created if it does not exist. The staging area is a directory path generated /// from the ROM's original file system location.</remarks> public static string GetStagingAreaPath(this IRom rom, string baseRomStagingArea) { var stagingAreaDirectory = System.IO.Path.GetDirectoryName(rom.RomPath).GetHashCode().ToString("x8"); var isAlternateRom = rom.IsAlternateRom(); if (isAlternateRom) { stagingAreaDirectory = System.IO.Path.GetDirectoryName(rom.OriginalRom().RomPath).GetHashCode().ToString("x8"); } var stagingAreaPath = System.IO.Path.Combine(baseRomStagingArea, stagingAreaDirectory); if (!System.IO.Directory.Exists(stagingAreaPath)) { System.IO.Directory.CreateDirectory(stagingAreaPath); } return(stagingAreaPath); }
/// <summary> /// Initializes a new instance of the ProgramSupportFiles. /// </summary> /// <param name="programRom">The ROM for which to track support files.</param> /// <param name="boxPath">The path to the default box art to use.</param> /// <param name="manualPath">The path to the default manual cover art to use.</param> /// <param name="manualTextPath">The path to the default manual text to use.</param> /// <param name="overlayPath">The path to the default overlay art to use.</param> /// <param name="labelPath">The path to the default label art to use.</param> public ProgramSupportFiles(IRom programRom, string boxPath, string manualPath, string manualTextPath, string overlayPath, string labelPath) { _programRom = programRom; _supportFiles = new Dictionary <ProgramFileKind, List <string> >(); _supportFileStates = new Dictionary <ProgramFileKind, ProgramSupportFileState>(); _supportFiles[ProgramFileKind.Rom] = new List <string>(); _supportFiles[ProgramFileKind.CfgFile] = new List <string>(); _supportFiles[ProgramFileKind.Box] = new List <string>(); _supportFiles[ProgramFileKind.Label] = new List <string>(); _supportFiles[ProgramFileKind.Overlay] = new List <string>(); _supportFiles[ProgramFileKind.ManualCover] = new List <string>(); _supportFiles[ProgramFileKind.ManualText] = new List <string>(); _supportFiles[ProgramFileKind.SaveData] = new List <string>(); _supportFiles[ProgramFileKind.LuigiFile] = new List <string>(); _supportFiles[ProgramFileKind.Vignette] = new List <string>(); _supportFiles[ProgramFileKind.GenericSupportFile] = new List <string>(); }
public static void Gentrify(IGame game) { string platform = game.Platform; platform = Regex.Replace(platform, @"[\s-]", "_"); platform = Regex.Replace(platform, @"^[0-9]", "_"); Type type = Type.GetType("Packager.Platforms." + platform); if (type == null) { type = Type.GetType("Packager.Platforms.Generic"); } IRom rom = (IRom)Activator.CreateInstance(type, game); rom.Package(); }
/// <summary> /// Gets the original <see cref="IRom"/> referred to by <paramref name="rom"/>. /// </summary> /// <param name="rom">The ROM whose original is desired.</param> /// <returns>The original ROM. Unless <paramref name="rom"/> refers to a ROM located on external devices, and that device is not accessible, this is usually just <paramref name="rom"/>.</returns> public static IRom OriginalRom(this IRom rom) { var originalRom = rom; var alternateRom = Rom.AsSpecificRomType <AlternateRom>(rom); if (alternateRom != null) { originalRom = alternateRom.Original; } else { var xmlRom = Rom.AsSpecificRomType <XmlRom>(rom); if (xmlRom != null) { originalRom = xmlRom.ResolvedRom; } } return(originalRom); }
/// <summary> /// Checks if the given ROM's CRC data matches the given program identifier with selectable strictness. See remarks. /// </summary> /// <param name="rom">The ROM to check for a match.</param> /// <param name="programIdentifier">The program identifier to match.</param> /// <param name="cfgCrcMustMatch">If <c>true</c> and a .BIN format ROM is being checked, determines whether the CRC of the config file must match as well.</param> /// <returns><c>true</c> if <paramref name="rom"/>'s CRC data matches the given <paramref name="programIdentifier"/>, <c>false</c> otherwise.</returns> /// <remarks><para>For .BIN format ROMs, there is the possibility, depending on the value if <paramref name="cfgCrcMustMatch"/>, that a match is reported, even though /// the .CFG file could have a profound impact on the actual ROM being used. The .CFG file can actually cause modifications to the ROM itself, or describe different /// features in the ROM (e.g. different compatibility or metadata). While metadata and compatibility differences could be considered cosmetic only, they can affect /// how the ROM is handled by hardware in the case of LTO Flash! for example. Most important of course is the matter of the memory map, RAM mappings, or actual /// code modification (e.g. the patch for Dreadnaught Factor for PAL systems). That said, until .CFG CRC values are computed on a 'canonicalized' form of the .CFG /// file, it is important to note that mere whitespace changes will cause .CFG mismatches, making it fragile to do full compares when working with database.</para> /// <para>Similarly, when working with the .ROM format, it is important to note that at this time, the CRC is computed for the entire file, including metadata that /// may be provided. This means that mismatches can occur because a documentation credit was modified in the metadata of one version of the file, even though /// the executable ROM itself was not changed.</para> /// <para>Finally, for the LUIGI format, there is an additional challenge. To this point, this ROM format is only used as the destination format for ROMs copied to /// the LTO Flash! hardware, though the jzIntv emulator supports it as well. As such, it is more than a container format for .BIN or .ROM formats, as it is different /// in several important ways. However, it has not yet (and possibly will never become) a target ROM format. It addresses some deficiencies in the original .ROM format /// that parallel the limitations of the original Intellicart and CuttleCart 3 hardware. That said, in theory the LUIGI header's UID entry poses a challenge. If the /// LUIGI file was created from a .ROM-format ROM, it is unambiguous. However, thereafter it is not clear if the file was created directly from the assembler, in which /// case the UID contains an as-yet-to-be-defined strong hash of something, or wither it contains a pair of 32-bit CRC values, one from the .BIN file, the other from /// the corresponding .CFG file. Given the nature of more modern Intellivision programs to commonly stray from the standard set of common .CFG files (and memory maps), /// it will be an interesting challenge to distinguish a LUIGI created via bin2luigi from one created directly by the assembler. In such a case, most likely we'd want /// to bump the version number of the LUIGI header and at least set a flag somewhere in the sea of bits that we swim through to figure out all these intricacies.</para></remarks> public static bool MatchesProgramIdentifier(this IRom rom, ProgramIdentifier programIdentifier, bool cfgCrcMustMatch) { var match = false; if (rom != null) { switch (rom.Format) { case RomFormat.Bin: match = (programIdentifier.DataCrc == rom.Crc) && (!cfgCrcMustMatch || (programIdentifier.OtherData == rom.CfgCrc)); break; case RomFormat.Rom: case RomFormat.CuttleCart3: case RomFormat.CuttleCart3Advanced: match = programIdentifier.DataCrc == rom.Crc; break; case RomFormat.Luigi: var luigiHeader = rom.GetLuigiHeader(); if (luigiHeader != null) { match = programIdentifier.Id == luigiHeader.Uid; // probably will never use this result, but... if (luigiHeader.OriginalRomFormat == RomFormat.Bin) { match = (programIdentifier.DataCrc == luigiHeader.OriginalRomCrc32) && (!cfgCrcMustMatch || (programIdentifier.OtherData == luigiHeader.OriginalCfgCrc32)); } else if (luigiHeader.OriginalRomFormat == RomFormat.Rom) { match = programIdentifier.DataCrc == luigiHeader.OriginalRomCrc32; } // else .. Should we throw here? This situation (as of 2. Sept. 2018) cannot exist. } break; default: throw new InvalidOperationException(); } } return(match); }
/// <inheritdoc /> public override int Compare(IRom x, IProgramInformation programInformationRomX, IRom y, IProgramInformation programInformationRomY) { var result = -1; if (NeedsDetailedCompare(x, y, out result)) { result = (int)x.Format - (int)y.Format; if (result == 0) { result = (int)x.Crc - (int)y.Crc; } if (((x.Format == RomFormat.None) && (x.Crc == 0)) || ((x.Crc == 0) && (y.Crc == 0))) { // Both ROMs in the comparison are missing -- and both have the same CRC - which was zero. // In such a case, try comparing the paths. result = string.Compare(x.RomPath, y.RomPath); } } return(result); }
/// <summary> /// Initializes a new instance of ProgramDescription. /// </summary> /// <param name="crc">The CRC of the program.</param> /// <param name="rom">The ROM file or files.</param> /// <param name="programInfo">Additional information about the program.</param> public ProgramDescription(uint crc, IRom rom, IProgramInformation programInfo) { _crc = crc; _rom = rom; _programInfo = new UserSpecifiedProgramInformation(programInfo); _xmlVendor = new MetadataString() { Text = _programInfo.Vendor }; _name = _programInfo.GetNameForCrc(crc); _xmlName = new MetadataString() { Text = _name }; _shortName = programInfo.ShortName; _xmlShortName = new MetadataString() { Text = _shortName }; _programFiles = new ProgramSupportFiles(rom); var allIncompatibilities = _programInfo.Crcs.Select(c => c.Incompatibilities); var crcData = _programInfo.Crcs.First(c => c.Crc == crc); var romSpecificIncompatibilities = crcData.Incompatibilities; if ((romSpecificIncompatibilities != IncompatibilityFlags.None) || (allIncompatibilities.Distinct().Count() > 1)) { var incompatibilities = _programInfo.Features.ToIncompatibilityFlags(); if (romSpecificIncompatibilities != incompatibilities) { _features = romSpecificIncompatibilities.ApplyFlagsToProgramFeatures(_programInfo.Features.Clone()); } else { _features = programInfo.Features; } } else { _features = programInfo.Features; } }
/// <summary> /// Get a specific implementation of IRom. /// </summary> /// <typeparam name="T">The specific IRom implementation to get.</typeparam> /// <param name="rom">The ROM whose specific implementation is desired.</param> /// <returns>The <paramref name="rom"/> as a specific implementation, or <c>null</c> if <paramref name="rom"/> is not the requested implementation.</returns> internal static T AsSpecificRomType <T>(IRom rom) where T : class, IRom { var specificRomType = rom as T; if (specificRomType == null) { var xmlRom = rom as XmlRom; if (xmlRom != null) { specificRomType = xmlRom.ResolvedRom as T; } } if (specificRomType == null) { var alternateRom = rom as AlternateRom; if (alternateRom != null) { specificRomType = alternateRom.Alternate as T; } } return(specificRomType); }
/// <summary> /// Gets the application to use to convert the ROM file. /// </summary> /// <param name="rom">The ROM file to be converted.</param> /// <param name="jzIntvConfiguration">The configuration used to locate the proper conversion tool.</param> /// <returns>The fully qualified path to the converter program.</returns> public static string GetConverterApp(this IRom rom, INTV.JzIntv.Model.Configuration jzIntvConfiguration) { string converterApp = null; switch (rom.Format) { case RomFormat.Bin: converterApp = jzIntvConfiguration.GetProgramPath(INTV.JzIntv.Model.ProgramFile.Bin2Luigi); break; case RomFormat.Intellicart: case RomFormat.CuttleCart3: case RomFormat.CuttleCart3Advanced: converterApp = jzIntvConfiguration.GetProgramPath(INTV.JzIntv.Model.ProgramFile.Rom2Luigi); break; case RomFormat.Luigi: converterApp = JustCopy; break; } return(converterApp); }
private static int CheckCrcs(IRom x, IProgramInformation programInformationRomX, IRom y, IProgramInformation programInformationRomY) { var cfgCrcRomX = x.CfgCrc; var cfgCrcRomY = y.CfgCrc; var result = (int)cfgCrcRomX - (int)cfgCrcRomY; if ((result != 0) && ((cfgCrcRomX == 0) || (cfgCrcRomY == 0))) { if (cfgCrcRomX == 0) { var programInfo = programInformationRomX; if (programInfo == null) { programInfo = x.GetProgramInformation(); } var cfgFilePath = x.GetStockCfgFile(programInfo); if (!string.IsNullOrEmpty(cfgFilePath)) { cfgCrcRomX = INTV.Core.Utility.Crc32.OfFile(cfgFilePath); } } if (cfgCrcRomY == 0) { var programInfo = programInformationRomY; if (programInfo == null) { programInfo = y.GetProgramInformation(); } var cfgFilePath = y.GetStockCfgFile(programInfo); if (!string.IsNullOrEmpty(cfgFilePath)) { cfgCrcRomY = INTV.Core.Utility.Crc32.OfFile(cfgFilePath); } } result = (int)cfgCrcRomX - (int)cfgCrcRomY; } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="INTV.Core.Model.Program.RomFileMetadataProgramInformation"/> class. /// </summary> /// <param name="rom">The ROM whose metadata program information is desired. If not a RomFormatRom, the /// metadata will be empty, and the features will be generic unrecognized ROM features.</param> public RomFileMetadataProgramInformation(IRom rom) { _features = ProgramFeatures.GetUnrecognizedRomFeatures(); Metadata = Enumerable.Empty <RomMetadataBlock>(); var romFormatRom = Rom.AsSpecificRomType <RomFormatRom>(rom); if (romFormatRom != null) { Metadata = romFormatRom.Metadata; var stringMetaData = Metadata.FirstOrDefault(m => m.Type == RomMetadataIdTag.Title) as RomMetadataString; if ((stringMetaData != null) && !string.IsNullOrEmpty(stringMetaData.StringValue)) { _title = stringMetaData.StringValue; } stringMetaData = Metadata.FirstOrDefault(m => m.Type == RomMetadataIdTag.ShortTitle) as RomMetadataString; if ((stringMetaData != null) && !string.IsNullOrEmpty(stringMetaData.StringValue)) { _shortName = stringMetaData.StringValue; } var date = Metadata.OfType <RomMetadataDate>().FirstOrDefault(d => d.Type == RomMetadataIdTag.ReleaseDate); if ((date != null) && date.Date.Flags.HasFlag(MetadataDateTimeFlags.Year)) { _year = date.Date.Date.Year.ToString(); } var vendor = Metadata.OfType <RomMetadataPublisher>().FirstOrDefault(); if (vendor != null) { _vendor = vendor.Publisher; } var features = Metadata.OfType <RomMetadataFeatures>().FirstOrDefault(); if (features != null) { _features = features.Features; } _crc = new CrcData(romFormatRom.Crc, string.Empty, _features.ToIncompatibilityFlags()); } }
/// <summary> /// Initializes a new instance of the <see cref="INTV.LtoFlash.Model.CacheIndexEntry"/> class. /// </summary> /// <param name="rom">The ROM described the entry.</param> /// <param name="romAbsolutePath">Absolute path to the ROM.</param> public CacheIndexEntry(IRom rom, string romAbsolutePath) { var romStagingArea = SingleInstanceApplication.Instance.GetConfiguration <Configuration>().RomsStagingAreaPath; RomPath = romAbsolutePath.Substring(romStagingArea.Length + 1); RomCrc32 = rom.Crc; RomSize = (uint)(new FileInfo(romAbsolutePath)).Length; if (rom.Format == RomFormat.Bin) { var cfgFilePath = Path.ChangeExtension(romAbsolutePath, ProgramFileKind.CfgFile.FileExtension()); if (File.Exists(cfgFilePath)) { CfgPath = cfgFilePath.Substring(romStagingArea.Length + 1); CfgCrc32 = INTV.Core.Utility.Crc32.OfFile(cfgFilePath); CfgSize = (uint)(new FileInfo(cfgFilePath)).Length; } } var luigiFilePath = rom.GetLtoFlashFilePath(); LuigiPath = luigiFilePath.Substring(romStagingArea.Length + 1); if (!System.IO.File.Exists(luigiFilePath) && LuigiFileHeader.PotentialLuigiFile(romAbsolutePath)) { // This has been known to happen in the transition between naming conventions, but also arises generally when // a ROM in the main ROM list has always been a LUIGI file. We have an original LUIGI file, // and find a cache entry, and are updating it -- we may not have the newly named LUIGI file yet. So, just copy it. // What happens is, *in the cache* we found foo.luigi, but the cached file path has become foo_luigi.luigi. if (System.IO.File.Exists(romAbsolutePath)) { System.IO.File.Copy(romAbsolutePath, luigiFilePath, true); } } LuigiCrc24 = INTV.Core.Utility.Crc24.OfFile(luigiFilePath); LuigiSize = (uint)(new FileInfo(luigiFilePath)).Length; }
/// <summary> /// Downloads a ROM to an Intellicart. /// </summary> /// <param name="intellicart">The Intellicart to load the ROM onto.</param> /// <param name="programName">Name of the program being downloaded.</param> /// <param name="rom">The ROM to load.</param> /// <param name="errorHandler">Error handler function.</param> public static void DownloadRom(this IntellicartModel intellicart, string programName, IRom rom, Action <string, Exception> errorHandler) { var title = string.Format(CultureInfo.CurrentCulture, Resources.Strings.DownloadRom_Title_Format, programName); var task = new AsyncTaskWithProgress(title, true, true, 0); var taskData = new DownloadTaskData(task, intellicart, programName, rom); taskData.ErrorHandler = errorHandler; task.RunTask(taskData, DownloadRom, DownloadRomComplete); }
/// <summary> /// Checks the given ROM to determine if it is operating as an alternative version (referring to a backup location). /// </summary> /// <param name="rom">The <see cref="IRom"/> to check.</param> /// <returns><c>true</c> if <paramref name="rom"/> refers to an alternative location of the ROM and its configuration file.</returns> public static bool IsAlternateRom(this IRom rom) { return(rom is AlternateRom); }
/// <inheritdoc /> public override int Compare(IRom x, IProgramInformation programInformationRomX, IRom y, IProgramInformation programInformationRomY) { var result = base.Compare(x, programInformationRomX, y, programInformationRomY); if ((result == 0) && (x != null)) { switch (x.Format) { case RomFormat.Bin: result = CheckCrcs(x, programInformationRomX, y, programInformationRomY); break; case RomFormat.Luigi: result = CheckCrcs(x, programInformationRomX, y, programInformationRomY); if ((result == 0) && (y.Format == RomFormat.Luigi)) { // It's possible LUIGI files' original CRCs match, but the LUIGI files themselves do not. // This once occurred when additional bytes were somehow appended to a downloaded LUIGI. In // that case, all the CRC data matched, so even the "strict" CRC check, which compared the // full 8 bytes of the ID in the header, still matched. However, the additional data at the // end of the corrupted file resulted in failure to load on LTO Flash! hardware. Therefore, // when comparing what appear to be two identical LUIGI files, still compare full file CRCs. result = (int)(Rom.AsSpecificRomType <LuigiFormatRom>(x).Crc24 - Rom.AsSpecificRomType <LuigiFormatRom>(y).Crc24); } break; default: break; } } return(result); }
public TestProgramDescription(IRom rom) : this() { Rom = rom; }
/// <summary> /// Initializes a new instance of fork associated with a host PC file system file. /// </summary> /// <param name="rom">The ROM for the fork.</param> public Fork(IRom rom) : this() { Rom = rom; FilePath = rom.PrepareForDeployment(LuigiGenerationMode.Standard); }
public CfgFileMetadataProgramInformation(IRom rom) { _features = ProgramFeatures.GetUnrecognizedRomFeatures(); Metadata = Enumerable.Empty <CfgVarMetadataBlock>(); var binFormatRom = Rom.AsSpecificRomType <BinFormatRom>(rom); if (binFormatRom != null) { Metadata = binFormatRom.Metadata; var stringMetaData = Metadata.FirstOrDefault(m => m.Type == CfgVarMetadataIdTag.Name) as CfgVarMetadataString; if ((stringMetaData != null) && !string.IsNullOrEmpty(stringMetaData.StringValue)) { _title = stringMetaData.StringValue; } stringMetaData = Metadata.FirstOrDefault(m => m.Type == CfgVarMetadataIdTag.ShortName) as CfgVarMetadataString; if ((stringMetaData != null) && !string.IsNullOrEmpty(stringMetaData.StringValue)) { _shortName = stringMetaData.StringValue; } var date = Metadata.OfType <CfgVarMetadataDate>().FirstOrDefault(d => d.Type == CfgVarMetadataIdTag.ReleaseDate); if ((date != null) && date.Date.Flags.HasFlag(MetadataDateTimeFlags.Year)) { _year = date.Date.Date.Year.ToString(); } var vendor = Metadata.FirstOrDefault(m => m.Type == CfgVarMetadataIdTag.Publisher) as CfgVarMetadataString; if (vendor != null) { _vendor = vendor.StringValue; } // NOTE: If these are specified multiple times, the 'last one wins' rule will be in effect. // That's technically OK, since the behavior is unspecified. From as1600.txt: // // Lines marked with a "*" can be repeated. For example, if a game has multiple // authors, you can list them all with their own author variable. Likewise, if // a program was released multiple times, you can give a list of release dates. // // For other values, repeating a variable does not have a well defined meaning. // Typically (but not always), the first instance takes precedence. // // So in the case of specifying features multiple times, this code will result in // 'last one wins'. foreach (var feature in Metadata.OfType <CfgVarMetadataFeatureCompatibility>()) { switch (feature.Type) { case CfgVarMetadataIdTag.Ecs: case CfgVarMetadataIdTag.EcsCompatibility: _features.Ecs = (EcsFeatures)feature.Compatibility; break; case CfgVarMetadataIdTag.Voice: case CfgVarMetadataIdTag.IntellivoiceCompatibility: _features.Intellivoice = feature.Compatibility; break; case CfgVarMetadataIdTag.IntellivisionII: case CfgVarMetadataIdTag.IntellivisionIICompatibility: _features.IntellivisionII = feature.Compatibility; break; case CfgVarMetadataIdTag.KeyboardComponentCompatibility: _features.KeyboardComponent = (KeyboardComponentFeatures)feature.Compatibility; break; case CfgVarMetadataIdTag.TutorvisionCompatibility: _features.Tutorvision = feature.Compatibility; break; case CfgVarMetadataIdTag.JlpAccelerators: case CfgVarMetadataIdTag.Jlp: _features.Jlp = (JlpFeatures)feature.Compatibility; if (_features.Jlp != JlpFeatures.Incompatible) { _features.JlpHardwareVersion = JlpHardwareVersion.Jlp03; // Assume minimal hardware version needed if (_features.Jlp > JlpFeatures.Tolerates) { // Flash storage is indicated, so check for it. var flashStorage = Metadata.FirstOrDefault(m => m.Type == CfgVarMetadataIdTag.JlpFlash) as CfgVarMetadataInteger; if ((flashStorage != null) && (flashStorage.IntegerValue > 0)) { // TODO: Min value checking here? _features.JlpFlashMinimumSaveSectors = (ushort)flashStorage.IntegerValue; _features.Jlp |= JlpFeatures.SaveDataRequired; } } } break; default: break; } } var ltoMapper = Metadata.FirstOrDefault(m => m.Type == CfgVarMetadataIdTag.LtoFlashMapper) as CfgVarMetadataBoolean; if (ltoMapper != null) { _features.LtoFlash = LtoFlashFeatures.Requires | LtoFlashFeatures.LtoFlashMemoryMapped; } _crc = new CrcData(binFormatRom.Crc, string.Empty, _features.ToIncompatibilityFlags()); } }
/// <summary> /// Initializes a new instance of the <see cref="INTV.Intellicart.Model.DownloadTaskData"/> class. /// </summary> /// <param name="task">The asynchronous task that will use this data.</param> /// <param name="intellicart">The Intellicart model to which a ROM is sent.</param> /// <param name="name">The name of the ROM being sent.</param> /// <param name="rom">The ROM being sent to an Intellicart.</param> internal DownloadTaskData(AsyncTaskWithProgress task, IntellicartModel intellicart, string name, IRom rom) : base(task) { Intellicart = intellicart; Name = name; Rom = rom; }
private ProgramDescription CreateProgramDescription(uint crc, IRom rom) { var programDescription = new ProgramDescription(crc, rom, new TestProgramInformation(crc)); return(programDescription); }
/// <summary> /// Gets an enumerable of the bytes to ignore for certain comparison operations. /// </summary> /// <param name="rom">The ROM whose ignorable data ranges for compare are needed.</param> /// <param name="excludeFeatureBits">If <c>true</c>, the result includes the range of bytes to ignore that describe ROM features.</param> /// <returns>An enumeration containing ranges of bytes to ignore for the purpose of comparing two LUIGI ROMs. For Version 1 and newer, /// this range will always include an entry for the UID portion of the LUIGI, which will allow for the comparison of two LUIGI files /// created from different sources (e.g. .rom vs. .bin) to actually compare as equivalent.</returns> public static IEnumerable <INTV.Core.Utility.Range <int> > GetComparisonIgnoreRanges(IRom rom, bool excludeFeatureBits) { var luigiFormatRom = AsSpecificRomType <LuigiFormatRom>(rom); if (luigiFormatRom != null) { foreach (var skipRange in luigiFormatRom.GetComparisonIgnoreRanges(excludeFeatureBits)) { yield return(skipRange); } } }
/// <summary> /// Identifies ROMs in a list of files and returns them. /// </summary> /// <param name="romFiles">A list of ROM files.</param> /// <param name="existingRoms">Existing, identified ROMs.</param> /// <param name="duplicateRoms">Receives ROMs that were not added because duplicates are already in the list.</param> /// <param name="acceptCancellation">A function that allows the operation to be cancelled.</param> /// <param name="progressFunc">A function to call to report progress of the search.</param> /// <param name="updateNumDiscovered">A function to call to indicate the number of valid ROMs discovered.</param> /// <param name="filter">Optional custom filter function. If filter is non-<c>null</c>, it must return <c>true</c> for a ROM to be added.</param> /// <returns>A list of program descriptions for the ROMs.</returns> public static IList <ProgramDescription> GatherRomsFromFileList(IEnumerable <IRom> romFiles, IEnumerable <ProgramDescription> existingRoms, IList <string> duplicateRoms, Func <bool> acceptCancellation, Action <string> progressFunc, Action <int> updateNumDiscovered, Func <IProgramInformation, bool> filter) { var addedItems = new List <ProgramDescription>(); #if DEBUGGING using (RomComparer strict = RomComparer.GetComparer(RomComparison.Strict), strictCrcOnly = RomComparer.GetComparer(RomComparison.StrictRomCrcOnly), canonical = RomComparer.GetComparer(RomComparison.CanonicalStrict), canonicalCrcOnly = RomComparer.GetComparer(RomComparison.CanonicalRomCrcOnly)) #else using (RomComparer comparer = RomComparer.GetComparer(RomComparer.DefaultCompareMode)) #endif // DEBUGGING { foreach (var romFile in romFiles) { if (acceptCancellation()) { break; } if (progressFunc != null) { progressFunc(romFile.RomPath); } bool alreadyAdded = (romFile.Crc != 0) && (addedItems.FirstOrDefault(p => p.Rom.IsEquivalentTo(romFile, comparer)) != null); if ((romFile.Crc != 0) && !alreadyAdded) { var programInfo = romFile.GetProgramInformation(); if ((filter == null) || filter(programInfo)) { var haveIt = existingRoms.Any(d => d.Rom.IsEquivalentTo(romFile, programInfo, comparer)); if (!haveIt) { IRom localRomCopy = null; if (romFile.RomPath.IsPathOnRemovableDevice()) { localRomCopy = romFile.CopyToLocalRomsDirectory(); } var programDescription = new ProgramDescription(romFile.Crc, romFile, programInfo); if (localRomCopy != null) { programDescription.Files.AddSupportFile(ProgramFileKind.Rom, localRomCopy.RomPath); } if ((romFile.Format == RomFormat.Bin) && (string.IsNullOrEmpty(romFile.ConfigPath) || !File.Exists(romFile.ConfigPath) || (localRomCopy != null))) { // Logic for .cfg file: // OnRemovableDevice: NO | YES // Has .cfg NO Create (no local copy made) | Create (local copy made, original is null, copy is from stock - if original changes, update copy of both ROM and .cfg) // YES Use (no local copy made) | Create (update if original changes) if (localRomCopy != null) { var cfgFilePath = localRomCopy.ConfigPath; if (string.IsNullOrEmpty(cfgFilePath) || !File.Exists(cfgFilePath)) { cfgFilePath = localRomCopy.GenerateStockCfgFile(programInfo); } if (!string.IsNullOrEmpty(cfgFilePath) && File.Exists(cfgFilePath)) { programDescription.Files.AddSupportFile(ProgramFileKind.CfgFile, cfgFilePath); } } else { var cfgFilePath = romFile.GenerateStockCfgFile(programInfo); if (!string.IsNullOrEmpty(cfgFilePath)) { romFile.UpdateCfgFile(cfgFilePath); } } } addedItems.Add(programDescription); if (updateNumDiscovered != null) { updateNumDiscovered(addedItems.Count); } } else if (duplicateRoms != null) { duplicateRoms.Add(romFile.RomPath); } } } else if (alreadyAdded && (duplicateRoms != null)) { duplicateRoms.Add(romFile.RomPath); } else if ((romFile != null) && ((romFile.Crc == 0) || (romFile.Crc == INTV.Core.Utility.Crc32.InitialValue) || !romFile.IsValid)) { // TODO: Report rejected ROMs? } } } return(addedItems); }
/// <summary> /// Gets a program's descriptive information by introspection assuming standard ROM layout. /// </summary> /// <param name="rom">The ROM to inspect.</param> /// <returns>Information about the ROM, ordered as described by RomInfoIndex.</returns> public static IEnumerable <string> GetRomInformation(this IRom rom) { return(GetRomInfo(rom)); }
/// <summary> /// Update the config file path of a ROM. /// </summary> /// <param name="rom">The ROM whose config file path is being updated.</param> /// <param name="cfgFile">The new config file path.</param> public static void UpdateCfgFile(this IRom rom, string cfgFile) { Rom.ReplaceCfgPath(rom, cfgFile); }
public static void LoadRom(string path) => cart = RomFactory.LoadRom(path);