Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
 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);
     }
 }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <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>();
 }
Exemple #8
0
        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();
        }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        /// <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);
        }
Exemple #11
0
        /// <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;
            }
        }
Exemple #13
0
        /// <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);
        }
Exemple #14
0
        /// <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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        /// <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());
            }
        }
Exemple #17
0
        /// <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;
        }
Exemple #18
0
        /// <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);
        }
Exemple #19
0
 /// <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);
 }
Exemple #20
0
        /// <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;
 }
Exemple #22
0
 /// <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);
 }
Exemple #23
0
        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());
            }
        }
Exemple #24
0
 /// <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;
 }
Exemple #25
0
        private ProgramDescription CreateProgramDescription(uint crc, IRom rom)
        {
            var programDescription = new ProgramDescription(crc, rom, new TestProgramInformation(crc));

            return(programDescription);
        }
Exemple #26
0
        /// <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);
        }
Exemple #28
0
 /// <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));
 }
Exemple #29
0
 /// <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);
 }
Exemple #30
0
 public static void LoadRom(string path) => cart = RomFactory.LoadRom(path);