Пример #1
0
        public static string LuaAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection["Global", "Lua"].Path;

            return(collection.AbsolutePathFor(path, null));
        }
Пример #2
0
 public static string FirmwareAbsolutePath(this PathEntryCollection collection)
 {
     return(collection.AbsolutePathFor(collection.FirmwaresPathFragment, null));
 }
Пример #3
0
 /// <summary>
 /// Returns the base path of the given system.
 /// If the system can not be found, an empty string is returned
 /// </summary>
 public static string BaseFor(this PathEntryCollection collection, string systemId)
 {
     return(string.IsNullOrWhiteSpace(systemId)
                         ? ""
                         : collection[systemId, "Base"]?.Path ?? "");
 }
Пример #4
0
        public static string MovieBackupsAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection["Global", "Movie backups"].Path;

            return(collection.AbsolutePathFor(path, null));
        }
 /// <summary>
 /// Returns an absolute path for the given relative path.
 /// If provided, the systemId will be used to generate the path.
 /// Wildcards are supported.
 /// Logic will fallback until an absolute path is found,
 /// using Global Base as a last resort
 /// </summary>
 public static string AbsolutePathFor(this PathEntryCollection collection, string path, string systemId)
 {
     // warning: supposedly Path.GetFullPath accesses directories (and needs permissions)
     // if this poses a problem, we need to paste code from .net or mono sources and fix them to not pose problems, rather than homebrew stuff
     return(Path.GetFullPath(collection.AbsolutePathForInner(path, systemId)));
 }
        private static string AbsolutePathForInner(this PathEntryCollection collection, string path, string systemId)
        {
            // Hack
            if (systemId == "Global")
            {
                return(collection.AbsolutePathForInner(path, systemId: null));
            }

            // This function translates relative path and special identifiers in absolute paths
            if (path.Length < 1)
            {
                return(collection.GlobalBaseAbsolutePath());
            }

            if (path == "%recent%")
            {
                return(Environment.SpecialFolder.Recent.ToString());
            }

            if (path.StartsWith("%exe%"))
            {
                return(PathUtils.ExeDirectoryPath + path.Substring(5));
            }

            if (path.StartsWith("%rom%"))
            {
                return(collection.LastRomPath + path.Substring(5));
            }

            if (path[0] == '.')
            {
                if (!string.IsNullOrWhiteSpace(systemId))
                {
                    path = path.Remove(0, 1);
                    path = path.Insert(0, collection.BaseFor(systemId));
                }

                if (path.Length == 1)
                {
                    return(collection.GlobalBaseAbsolutePath());
                }

                if (path[0] == '.')
                {
                    path = path.Remove(0, 1);
                    path = path.Insert(0, collection.GlobalBaseAbsolutePath());
                }

                return(path);
            }

            if (Path.IsPathRooted(path))
            {
                return(path);
            }

            //handling of initial .. was removed (Path.GetFullPath can handle it)
            //handling of file:// or file:\\ was removed  (can Path.GetFullPath handle it? not sure)

            // all bad paths default to EXE
            return(PathUtils.ExeDirectoryPath);
        }
 /// <summary>
 /// Returns an entry for the given system and pathType (ROM, screenshot, etc)
 /// but falls back to the base system or global system if it fails
 /// to find pathType or systemId
 /// </summary>
 public static PathEntry EntryWithFallback(this PathEntryCollection collection, string pathType, string systemId)
 {
     return((collection[systemId, pathType]
             ?? collection[systemId, "Base"])
            ?? collection[PathEntryCollection.GLOBAL, "Base"]);
 }
        public static string ToolsAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection[PathEntryCollection.GLOBAL, "Tools"].Path;

            return(collection.AbsolutePathFor(path, null));
        }
 public static string PalettesAbsolutePathFor(this PathEntryCollection collection, string systemId)
 {
     return(collection.AbsolutePathFor(collection[systemId, "Palettes"].Path, systemId));
 }
Пример #10
0
 /// <summary>
 /// Takes an absolute path and attempts to convert it to a relative, based on the system,
 /// or global base if no system is supplied, if it is not a subfolder of the base, it will return the path unaltered
 /// </summary>
 public static string TryMakeRelative(this PathEntryCollection collection, string absolutePath, string system = null) => absolutePath.MakeRelativeTo(
     string.IsNullOrWhiteSpace(system)
                         ? collection.GlobalBaseAbsolutePath()
                         : collection.AbsolutePathFor(collection.BaseFor(system), system)
     );
Пример #11
0
        public static string AutoSaveRamAbsolutePath(this PathEntryCollection collection, IGameInfo game, IMovie movie)
        {
            var path = collection.SaveRamAbsolutePath(game, movie);

            return(path.Insert(path.Length - 8, ".AutoSaveRAM"));
        }
Пример #12
0
        public static string MultiDiskAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection.ResolveToolsPath(collection[PathEntryCollection.GLOBAL, "Multi-Disk Bundles"].Path);

            return(collection.AbsolutePathFor(path, null));
        }
Пример #13
0
        public static string TastudioStatesAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection[PathEntryCollection.GLOBAL, "TAStudio states"].Path;

            return(collection.AbsolutePathFor(path, null));
        }
Пример #14
0
        public static string LogAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection.ResolveToolsPath(collection["Global", "Debug Logs"].Path);

            return(collection.AbsolutePathFor(path, null));
        }
Пример #15
0
        public static string AbsolutePathForType(this PathEntryCollection collection, string systemId, string type)
        {
            var path = collection.EntryWithFallback(type, systemId).Path;

            return(collection.AbsolutePathFor(path, systemId));
        }
Пример #16
0
        public static string WatchAbsolutePath(this PathEntryCollection collection)
        {
            var path = collection.ResolveToolsPath(collection["Global", "Watch (.wch)"].Path);

            return(collection.AbsolutePathFor(path, null));
        }
Пример #17
0
		public void DoScanAndResolve(PathEntryCollection pathEntries, IDictionary<string, string> userSpecifications)
		{
			// build a list of file sizes. Only those will be checked during scanning
			var sizes = new HashSet<long>();
			foreach (var ff in FirmwareDatabase.FirmwareFiles)
			{
				sizes.Add(ff.Size);
			}

			using var reader = new RealFirmwareReader();

			// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
			var todo = new Queue<DirectoryInfo>();
			todo.Enqueue(new DirectoryInfo(pathEntries.AbsolutePathFor(pathEntries.FirmwaresPathFragment, null)));
	
			while (todo.Count != 0)
			{
				var di = todo.Dequeue();

				if (!di.Exists)
				{
					continue;
				}

				// we're going to allow recursing into subdirectories, now. its been verified to work OK
				foreach (var subDir in di.GetDirectories())
				{
					todo.Enqueue(subDir);
				}
				
				foreach (var fi in di.GetFiles())
				{
					if (sizes.Contains(fi.Length))
					{
						reader.Read(fi);
					}
				}
			}

			// now, for each firmware record, try to resolve it
			foreach (var fr in FirmwareDatabase.FirmwareRecords)
			{
				// clear previous resolution results
				_resolutionDictionary.Remove(fr);

				// get all options for this firmware (in order)
				var fr1 = fr;
				var options = FirmwareDatabase.FirmwareOptions
						.Where(fo => fo.SystemId == fr1.SystemId
							&& fo.FirmwareId == fr1.FirmwareId
							&& fo.IsAcceptableOrIdeal);

				// try each option
				foreach (var fo in options)
				{
					var hash = fo.Hash;

					// did we find this firmware?
					if (reader.Dict.ContainsKey(hash))
					{
						// rad! then we can use it
						var ri = new ResolutionInfo
						{
							FilePath = reader.Dict[hash].FileInfo.FullName,
							KnownFirmwareFile = FirmwareDatabase.FirmwareFilesByHash[hash],
							Hash = hash,
							Size = fo.Size
						};
						_resolutionDictionary[fr] = ri;
						goto DONE_FIRMWARE;
					}
				}

				DONE_FIRMWARE: ;
			}

			// apply user overrides
			foreach (var fr in FirmwareDatabase.FirmwareRecords)
			{
				// do we have a user specification for this firmware record?
				if (userSpecifications.TryGetValue(fr.ConfigKey, out var userSpec))
				{
					// flag it as user specified
					if (!_resolutionDictionary.TryGetValue(fr, out ResolutionInfo ri))
					{
						ri = new ResolutionInfo();
						_resolutionDictionary[fr] = ri;
					}

					ri.UserSpecified = true;
					ri.KnownFirmwareFile = null;
					ri.FilePath = userSpec;
					ri.Hash = null;

					// check whether it exists
					var fi = new FileInfo(userSpec);
					if (!fi.Exists)
					{
						ri.Missing = true;
						continue;
					}

					// compute its hash
					RealFirmwareFile rff;
					// NDS's firmware file contains user settings; these are over-written by sync settings, so we shouldn't allow them to impact the hash
					if (fr.SystemId == "NDS" && fr.FirmwareId == "firmware")
						rff = reader.Read(new FileInfo(Emulation.Cores.Consoles.Nintendo.NDS.MelonDS.CreateModifiedFirmware(userSpec)));
					else
						rff = reader.Read(fi);
					ri.Size = fi.Length;
					ri.Hash = rff.Hash;

					// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesn't really use this information right now)
					if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out var ff))
					{
						ri.KnownFirmwareFile = ff;

						// if the known firmware file is for a different firmware, flag it so we can show a warning
						var option = FirmwareDatabase.FirmwareOptions
							.FirstOrDefault(fo => fo.Hash == rff.Hash && fo.ConfigKey != fr.ConfigKey);

						if (option != null)
						{
							ri.KnownMismatching = true;
						}
					}
				}
			} // foreach(firmware record)
		} // DoScanAndResolve()