private IProgramDescription GetProgramDescription(ProgramIdentifier programIdentifier, RomFormat format, string code) { IProgramDescription programDescription = null; if (DefaultDescriptionsSource != null) { // Try the strictest match first. programDescription = DefaultDescriptionsSource.FirstOrDefault(d => d.IsMatchingProgramDescription(programIdentifier, format, true, code)); if (programDescription == null) { programDescription = DefaultDescriptionsSource.FirstOrDefault(d => d.IsMatchingProgramDescription(programIdentifier, format, true)); } if (programDescription == null) { programDescription = DefaultDescriptionsSource.FirstOrDefault(d => d.IsMatchingProgramDescription(programIdentifier, format, false)); } if (programDescription == null) { programDescription = DefaultDescriptionsSource.FirstOrDefault(d => d.IsMatchingProgramDescription(programIdentifier)); } if (programDescription == null) { programDescription = DefaultDescriptionsSource.FirstOrDefault(d => d.Crc == programIdentifier.DataCrc); } } return(programDescription); }
private static void ValidateDescription(IProgramDescription expectedDescription, IProgramRomInformation actualInformation) { Assert.Equal(expectedDescription.Name, actualInformation.Title); Assert.Equal(expectedDescription.ShortName, actualInformation.ShortName); Assert.Equal(expectedDescription.Vendor, actualInformation.Vendor); Assert.Equal(expectedDescription.Year, actualInformation.Year); }
private static void BrowseAndDownload(object parameter) { if (CanBrowseAndDownload(parameter)) { var selectedFile = INTV.Shared.Model.IRomHelpers.BrowseForRoms(false, Resources.Strings.BrowseAndLaunchInJzIntvCommand_BrowseDialogPrompt).FirstOrDefault(); if (selectedFile != null) { var rom = selectedFile.GetRomFromPath(); IProgramDescription programDescription = null; if (rom != null) { var programInfo = rom.GetProgramInformation(); programDescription = new ProgramDescription(rom.Crc, rom, programInfo); } if (programDescription != null) { OnLaunch(programDescription); } else { var message = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.BrowseAndLaunchInJzIntvCommand_Failed_MessageFormat, selectedFile); OSMessageBox.Show(message, string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.BrowseAndLaunchInJzIntvCommand_Failed_Title)); } } } }
private bool AddFromIProgramDescription(IProgramDescription programDescription, IProgramRomInformationBuilder programInformationBuilder) { var built = programDescription != null; if (built) { AddBasicData(programInformationBuilder, programDescription.Name, programDescription.Vendor, programDescription.Year, programDescription.ShortName); } return(built); }
private IProgramInformation GetProgramInformation(IProgramDescription programDescription, ProgramIdentifier programIdentifier) { var programInformation = programDescription == null ? null : programDescription.ProgramInformation; if ((DefaultInformationSource != null) && (programInformation == null)) { programInformation = DefaultInformationSource.FindProgram(programIdentifier); } return(programInformation); }
/// <summary> /// Compares the instance to another <see cref="IProgramDescription"/>. /// </summary> /// <param name="other">The other <see cref="IProgramDescription"/> to compare against.</param> /// <returns>If this instance and <paramref name="other"/> are considered equivalent, returns zero. A non-zero value indicates inequality.</returns> /// <remarks>Consider implementing the IComparable / IComparer / IEquatable / IEqualityComparer interfaces on ProgramDescription instead? /// Deficiency noted here: https://github.com/intvsteve/VINTage/issues/239 </remarks> private int CompareToIProgramDescription(IProgramDescription other) { var result = 1; if (other != null) { // Always use strict comparer. result = RomComparer.GetDefaultComparerForMode(RomComparison.Strict).Compare(Rom, ProgramInformation, other.Rom, other.ProgramInformation); } return(result); }
/// <inheritdoc /> public override bool IsRomCompatible(IProgramDescription programDescription) { var isCompatible = programDescription.Features.Intellicart != IntellicartCC3Features.Incompatible; if (isCompatible) { // Some LUIGI ROMs cannot run on Intellicart! - specifically, LUIGI ROMs that are LTO Flash!-only. Check for that. isCompatible = !programDescription.Rom.IsLtoFlashOnlyRom(); } return(isCompatible); }
public void ProgramDescription_OperatorNullEquals_ReturnsFalse() { var information = new TestProgramInformation(); var crc = 1u; var name = "AgletMaster 5900"; information.AddCrc(crc, name); var description = new ProgramDescription(crc, null, information); IProgramDescription other = null; Assert.False(other == description); }
private IProgramFeatures GetInitialProgramFeatures(IProgramDescription programDescription, IProgramInformation programInformation) { IProgramFeatures initialProgramFeatures = null; if (programDescription != null) { initialProgramFeatures = programDescription.Features; } if ((initialProgramFeatures == null) && (programInformation != null)) { initialProgramFeatures = programInformation.Features; } return(initialProgramFeatures); }
private void RefreshProgramAvailabilityState(IProgramDescription description, IEnumerable <IPeripheral> peripherals, ProgramSupportFileState newState) { using (var comparer = RomComparer.GetComparer(RomComparer.DefaultCompareMode)) { // Should we be using the comparer here? foreach (var program in Items.OfType <ProgramViewModel>().Where(p => (p.ProgramDescription.Crc == description.Crc) && (p.ProgramDescription.Rom.RomPath == description.Rom.RomPath))) { program.RefreshValidationState(peripherals); } } foreach (var directory in Items.OfType <FolderViewModel>()) { directory.RefreshProgramAvailabilityState(description, peripherals, newState); } }
private IProgramMetadata GetInitialProgramMetadatda(IProgramDescription programDescription, IProgramInformation programInformation) { IProgramMetadata initialProgramMetadata = null; if ((programDescription != null) && (programDescription.Rom != null)) { initialProgramMetadata = programDescription.Rom.GetProgramMetadata(); } if ((initialProgramMetadata == null) && (programInformation != null)) { // Several implementations of IProgramInformation also implement IProgramMetadata. initialProgramMetadata = programInformation as IProgramMetadata; } return(initialProgramMetadata); }
/// <inheritdoc /> public bool IsRomCompatible(IProgramDescription programDescription) { var isCompatible = true; if (isCompatible) { var isLtoOnly = programDescription.Rom.IsLtoFlashOnlyRom(); if (IsValid) { isCompatible = programDescription.Rom.CanExecuteOnDevice(UniqueId); } else { isCompatible = !isLtoOnly; } } return(isCompatible); }
/// <summary> /// Determines if a given <see cref="IProgramDescription"/> is considered a match based on given criteria. /// </summary> /// <param name="programDescription">An instance</param> /// <param name="programIdentifier">Provides the unique identifier that must match the value that can be determined from <paramref name="programDescription"/>.</param> /// <param name="romFormat">If this value is not <see cref="RomFormat.None"/>, then <paramref name="programDescription"/> must have the same ROM format to be a match.</param> /// <param name="cfgCrcMustMatch">If <paramref name="romFormat"/> matches and is <see cref="RomFormat.Bin"/>, and this value is <c>true</c>, the CRC of the CFG file must also match.</param> /// <param name="code">If specified (not <c>null</c> or empty), and it can be determined that <paramref name="programDescription"/> has a value, value is used in determining match.</param> /// <returns><c>true</c> if all of the specified criteria match the corresponding data in <paramref name="programDescription"/>.</returns> /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="programDescription"/> is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if <paramref name="programIdentifier"/> is invalid.</exception> public static bool IsMatchingProgramDescription(this IProgramDescription programDescription, ProgramIdentifier programIdentifier, RomFormat romFormat, bool cfgCrcMustMatch, string code) { if (programDescription == null) { throw new ArgumentNullException("programDescription"); } if (programIdentifier == ProgramIdentifier.Invalid) { throw new ArgumentException("programIdentifier"); } var crcMatch = programDescription.Crc == programIdentifier.DataCrc; var cfgCrcsMatch = !cfgCrcMustMatch; var romFormatsMatch = romFormat == RomFormat.None; // don't care var codesMatch = string.IsNullOrEmpty(code); if (programDescription.Rom != null) { if (!romFormatsMatch) { romFormatsMatch = programDescription.Rom.MatchingRomFormat(romFormat, considerOriginalFormat: true); } crcMatch = programDescription.Rom.MatchesProgramIdentifier(programIdentifier, cfgCrcMustMatch); if (cfgCrcMustMatch) { cfgCrcsMatch = crcMatch; } } // This may be nearly worthless -- how many XML ProgramInformation implementations are hooked to ProgramDescriptions -- don't they all end up being UserSpecifiedProgramInformation? if (!codesMatch && programDescription.ProgramInformation is IntvFunhouseXmlProgramInformation) { codesMatch = ((IntvFunhouseXmlProgramInformation)programDescription.ProgramInformation).Code == code; } var match = crcMatch && cfgCrcsMatch && romFormatsMatch && codesMatch; return(match); }
private static void DownloadRom(IntellicartViewModel intellicart, IProgramDescription program) { if (program != null) { var isCompatible = intellicart.Model.IsRomCompatible(program); if (!isCompatible) { var message = string.Format(Resources.Strings.DownloadCommand_IncompatibleRom_Message_Format, program.Name); isCompatible = OSMessageBox.Show(message, Resources.Strings.DownloadCommand_IncompatibleRom_Title, OSMessageBoxButton.YesNo) == OSMessageBoxResult.Yes; } if (isCompatible) { if ((program != null) && (program.Rom != null) && !program.Rom.Validate()) { OSMessageBox.Show(string.Format(Resources.Strings.DownloadCommand_Missing_Message_Format, program.Name, program.Rom.RomPath), string.Format(Resources.Strings.DownloadCommand_Failed_Title_Format, program.Name)); } else { intellicart.Model.DownloadRom(program.Name, program.Rom, OnDownloadError); } } } }
public ProgramRunner(IResumeMediator resumeMediator, IProgramDescription programDescription, ILogger <ProgramRunner> logger) { _resumeMediator = resumeMediator; _programDescription = programDescription; _logger = logger; }
/// <inheritdoc /> public abstract bool IsRomCompatible(IProgramDescription programDescription);
public override bool IsRomCompatible(IProgramDescription programDescription) { return(false); }
/// <inheritdoc /> public override bool IsRomCompatible(IProgramDescription programDescription) { return(programDescription.Features.Ecs != EcsFeatures.Incompatible); }
/// <inheritdoc /> public bool IsRomCompatible(IProgramDescription programDescription) { // TODO: Perhaps this is not actually always the case. E.g. the standard GROM may not work for Tutorvision games? return(true); }
/// <summary> /// Marks all items that refer to the given description as available. /// </summary> /// <param name="description">The program description to mark as available.</param> /// <param name="peripherals">The peripherals attached to the system, used for compatibility checks.</param> public void MarkProgramAvailable(IProgramDescription description, IEnumerable <IPeripheral> peripherals) { RefreshProgramAvailabilityState(description, peripherals, ProgramSupportFileState.None); }
/// <summary> /// Determines if a given <see cref="IProgramDescription"/> is considered a match based on given criteria. /// </summary> /// <param name="programDescription">An instance</param> /// <param name="programIdentifier">Provides the unique identifier that must match the value that can be determined from <paramref name="programDescription"/>.</param> /// <param name="romFormat">If this value is not <see cref="RomFormat.None"/>, then <paramref name="programDescription"/> must have the same ROM format to be a match.</param> /// <param name="cfgCrcMustMatch">If <paramref name="romFormat"/> matches and is <see cref="RomFormat.Bin"/>, and this value is <c>true</c>, the CRC of the CFG file must also match.</param> /// <returns><c>true</c> if all of the specified criteria match the corresponding data in <paramref name="programDescription"/>.</returns> /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="programDescription"/> is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if <paramref name="programIdentifier"/> is invalid.</exception> public static bool IsMatchingProgramDescription(this IProgramDescription programDescription, ProgramIdentifier programIdentifier, RomFormat romFormat, bool cfgCrcMustMatch) { var match = IsMatchingProgramDescription(programDescription, programIdentifier, romFormat, cfgCrcMustMatch, null); return(match); }
/// <summary> /// Updates the validation state of the given support file. /// </summary> /// <param name="whichFile">Which file to validate.</param> /// <param name="crc">If non-zero, the CRC of the program ROM to compare against if validating the ROM file.</param> /// <param name="programDescription">The program description being validated (if applicable).</param> /// <param name="peripherals">The peripherals attached to the system, used for compatibility checks.</param> /// <param name="connectedPeripheralsHistory">The peripherals that have been attached to the system over time.</param> /// <param name="reportIfModified">If <c>true</c>, check if the file has been modified, not just whether it exists.</param> /// <returns>The updated state of the file.</returns> public ProgramSupportFileState ValidateSupportFile(ProgramFileKind whichFile, uint crc, IProgramDescription programDescription, IEnumerable <IPeripheral> peripherals, IEnumerable <IPeripheral> connectedPeripheralsHistory, bool reportIfModified) { var validationState = ProgramSupportFileState.None; switch (whichFile) { case ProgramFileKind.Rom: var isValid = Rom.Validate(); if (!string.IsNullOrEmpty(RomImagePath)) { var previousValidationState = ProgramSupportFileState.None; _supportFileStates.TryGetValue(whichFile, out previousValidationState); if (!StreamUtilities.FileExists(RomImagePath)) { validationState = ProgramSupportFileState.Missing; if (AlternateRomImagePaths.Any(p => StreamUtilities.FileExists(p))) { validationState = ProgramSupportFileState.MissingWithAlternateFound; } } else if (reportIfModified) { isValid = _programRom.IsValid; if (crc != 0) { // In some cases, the CRC provided is actually Rom.Crc, so if they match, recompute the CRC. var cfgCrc = 0u; isValid = (Rom.Crc == crc) && (crc == GetRefreshedCrcForRom(RomImagePath, RomConfigurationFilePath, out cfgCrc) && (Rom.CfgCrc == cfgCrc)); } validationState = isValid ? ProgramSupportFileState.PresentAndUnchanged : ProgramSupportFileState.PresentButModified; } switch (validationState) { case ProgramSupportFileState.PresentAndUnchanged: case ProgramSupportFileState.None: // Treat a ROM file's missing or modified state as higher priority to report than peripheral-related information. // This bit of code is entirely LTO Flash!-specific in its assumptions. If there should ever be other // peripheral-specific needs to address here, a larger architectural change may be necessary. While the // language of the states here is neutral, the basis of this check is not. var rom = programDescription == null ? Rom : programDescription.Rom; var requiresPeripheral = rom.IsLtoFlashOnlyRom(); if (requiresPeripheral) { var isUniversallyCompatible = rom.GetTargetDeviceUniqueId() == LuigiScrambleKeyBlock.AnyLTOFlashId; var matchesPeripheralInDeviceHistory = isUniversallyCompatible || ((connectedPeripheralsHistory != null) && (connectedPeripheralsHistory.FirstOrDefault(p => p.IsRomCompatible(programDescription)) != null)); var canRunOnConnected = isUniversallyCompatible || ((peripherals != null) && (peripherals.FirstOrDefault(p => p.IsRomCompatible(programDescription)) != null)); if (peripherals == null) { // If previous validation state was due to peripheral, retain it, since we don't // have any peripherals to check against. if (validationState != previousValidationState) { switch (previousValidationState) { case ProgramSupportFileState.RequiredPeripheralAvailable: case ProgramSupportFileState.RequiredPeripheralIncompatible: case ProgramSupportFileState.RequiredPeripheralNotAttached: case ProgramSupportFileState.RequiredPeripheralUnknown: validationState = previousValidationState; break; case ProgramSupportFileState.None: validationState = matchesPeripheralInDeviceHistory ? ProgramSupportFileState.RequiredPeripheralNotAttached : ProgramSupportFileState.RequiredPeripheralUnknown; break; default: // TODO: Decide if the following is a bug: // 0: Presume a scrambled (unique) LUIGI, no device or device history provided (null) // 1. Initially ROM's file is missing, but its alternate is found - this caches the 'MissingButAlternateFound' state // 2. Update ROM to use alternate path as primary path // 3. Re-validate // At this point, the "Present and unmodified" state is used -- despite the ROM requiring // a specific device. // Why is this considered correct at this time? // a) When no devices or device history are give (nulls), it's impossible to know. So just use the simple state of he file. // b) It MAY be a bug that, if we pass in EMPTY peripheral / history lists that we should consider something different... but // then again, should we report 'unknown peripheral' at that time? Or would reporting 'not attached' be better? // What about 'universally' scrambled ROMs? Using 'not attached' may be more accurate then as well... // The case of scrambled ROMs likely needs more careful consideration generally... break; } } } else { if (peripherals.Any()) { if (canRunOnConnected) { validationState = ProgramSupportFileState.RequiredPeripheralAvailable; } else { validationState = ProgramSupportFileState.RequiredPeripheralIncompatible; } } else { validationState = matchesPeripheralInDeviceHistory ? ProgramSupportFileState.RequiredPeripheralNotAttached : ProgramSupportFileState.RequiredPeripheralUnknown; } } } break; default: break; } } break; default: // TODO: Implement remaining validation code. break; } _supportFileStates[whichFile] = validationState; return(validationState); }
/// <summary> /// Determines if a given <see cref="IProgramDescription"/> is considered a match based on given criteria. /// </summary> /// <param name="programDescription">An instance</param> /// <param name="programIdentifier">Provides the unique identifier that must match the value that can be determined from <paramref name="programDescription"/>.</param> /// <returns><c>true</c> if all of the specified criteria match the corresponding data in <paramref name="programDescription"/>.</returns> /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="programDescription"/> is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if <paramref name="programIdentifier"/> is invalid.</exception> public static bool IsMatchingProgramDescription(this IProgramDescription programDescription, ProgramIdentifier programIdentifier) { var match = IsMatchingProgramDescription(programDescription, programIdentifier, RomFormat.None, false, null); return(match); }