diff --git a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs index a0005fac78..005bbec2bd 100644 --- a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs +++ b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs @@ -162,7 +162,7 @@ namespace BizHawk.Client.ApiHawk /// Savestate friendly name public static void LoadState(string name) { - InvokeMainFormMethod("LoadState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), $"{name}.State"), name, false, false }); + InvokeMainFormMethod("LoadState", new object[] { Path.Combine(Global.Config.PathEntries.SaveStateAbsolutePath(Global.Game.System), $"{name}.State"), name, false, false }); } @@ -245,7 +245,7 @@ namespace BizHawk.Client.ApiHawk /// Savestate friendly name public static void SaveState(string name) { - InvokeMainFormMethod("SaveState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), $"{name}.State"), name, false }); + InvokeMainFormMethod("SaveState", new object[] { Path.Combine(Global.Config.PathEntries.SaveStateAbsolutePath(Global.Game.System), $"{name}.State"), name, false }); } /// diff --git a/BizHawk.Client.Common/CoreFileProvider.cs b/BizHawk.Client.Common/CoreFileProvider.cs index 6f89c794f2..552edcf665 100644 --- a/BizHawk.Client.Common/CoreFileProvider.cs +++ b/BizHawk.Client.Common/CoreFileProvider.cs @@ -19,11 +19,13 @@ namespace BizHawk.Client.Common public string DllPath() => Path.Combine(PathManager.GetExeDirectoryAbsolute(), "dll"); + // Poop public string GetRetroSaveRAMDirectory(GameInfo game) - => PathManager.RetroSaveRAMDirectory(game); + => Global.Config.PathEntries.RetroSaveRamAbsolutePath(game, Global.MovieSession.Movie.IsActive(), Global.MovieSession.Movie.Filename); + // Poop public string GetRetroSystemPath(GameInfo game) - => PathManager.RetroSystemPath(game); + => Global.Config.PathEntries.RetroSystemAbsolutePath(game); private void FirmwareWarn(string sysID, string firmwareID, bool required, string msg = null) { diff --git a/BizHawk.Client.Common/FirmwareManager.cs b/BizHawk.Client.Common/FirmwareManager.cs index 3b91c1728c..73164666ee 100644 --- a/BizHawk.Client.Common/FirmwareManager.cs +++ b/BizHawk.Client.Common/FirmwareManager.cs @@ -151,7 +151,7 @@ namespace BizHawk.Client.Common // 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(); - todo.Enqueue(new DirectoryInfo(PathManager.MakeAbsolutePath(firmwaresPath, null))); + todo.Enqueue(new DirectoryInfo(Global.Config.PathEntries.AbsolutePathFor(firmwaresPath, null))); while (todo.Count != 0) { diff --git a/BizHawk.Client.Common/PathManager.cs b/BizHawk.Client.Common/PathManager.cs index 645092ac38..932ec07f8d 100644 --- a/BizHawk.Client.Common/PathManager.cs +++ b/BizHawk.Client.Common/PathManager.cs @@ -4,10 +4,7 @@ using System.IO; using System.Reflection; using BizHawk.Common; -using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; -using BizHawk.Emulation.Cores.Nintendo.SNES; -using BizHawk.Emulation.Cores.Nintendo.SNES9X; namespace BizHawk.Client.Common { @@ -15,7 +12,8 @@ namespace BizHawk.Client.Common { static PathManager() { - SetDefaultIniPath(MakeProgramRelativePath("config.ini")); + var defaultIni = Path.Combine(GetExeDirectoryAbsolute(), "config.ini"); + SetDefaultIniPath(defaultIni); } public static string GetExeDirectoryAbsolute() @@ -29,12 +27,16 @@ namespace BizHawk.Client.Common return path; } + // TODO: this always makes an absolute path! + // Needs to be fixed, the intent was to turn an absolute path + // into one relative to the exe + // for instance: C:\BizHawk\Lua becomes .\Lua (if EmuHawk.Exe is in C:\BizHawk) /// /// Makes a path relative to the %exe% directory /// public static string MakeProgramRelativePath(string path) { - return MakeAbsolutePath($"%exe%/{path}", null); + return Path.Combine(GetExeDirectoryAbsolute(), path); } public static string GetDllDirectory() @@ -52,137 +54,8 @@ namespace BizHawk.Client.Common DefaultIniPath = newDefaultIniPath; } - /// - /// Gets absolute base as derived from EXE - /// - public static string GetGlobalBasePathAbsolute() - { - var gbase = Global.Config.PathEntries.GlobalBaseFragment; - - // if %exe% prefixed then substitute exe path and repeat - if(gbase.StartsWith("%exe%",StringComparison.InvariantCultureIgnoreCase)) - gbase = GetExeDirectoryAbsolute() + gbase.Substring(5); - - //rooted paths get returned without change - //(this is done after keyword substitution to avoid problems though) - if (Path.IsPathRooted(gbase)) - return gbase; - - //not-rooted things are relative to exe path - gbase = Path.Combine(GetExeDirectoryAbsolute(), gbase); - - return gbase; - } - - public static string GetPlatformBase(string system) - { - return Global.Config.PathEntries[system, "Base"].Path; - } - - public static string StandardFirmwareName(string name) - { - return Path.Combine(MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null), name); - } - - public static string MakeAbsolutePath(string path, string system) - { - //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(MakeAbsolutePathInner(path, system)); - } - - static string MakeAbsolutePathInner(string path, string system) - { - // Hack - if (system == "Global") - { - system = null; - } - - // This function translates relative path and special identifiers in absolute paths - if (path.Length < 1) - { - return GetGlobalBasePathAbsolute(); - } - - if (path == "%recent%") - { - return Environment.SpecialFolder.Recent.ToString(); - } - - if (path.StartsWith("%exe%")) - return GetExeDirectoryAbsolute() + path.Substring(5); - if (path.StartsWith("%rom%")) - return Global.Config.LastRomPath + path.Substring(5); - - if (path[0] == '.') - { - if (!string.IsNullOrWhiteSpace(system)) - { - path = path.Remove(0, 1); - path = path.Insert(0, GetPlatformBase(system)); - } - - if (path.Length == 1) - { - return GetGlobalBasePathAbsolute(); - } - - if (path[0] == '.') - { - path = path.Remove(0, 1); - path = path.Insert(0, GetGlobalBasePathAbsolute()); - } - - 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 GetExeDirectoryAbsolute(); - } - - public static string RemoveParents(string path, string workingpath) - { - // determines number of parents, then removes directories from working path, return absolute path result - // Ex: "..\..\Bob\", "C:\Projects\Emulators\Bizhawk" will return "C:\Projects\Bob\" - int x = NumParentDirectories(path); - if (x > 0) - { - int y = path.HowMany("..\\"); - int z = workingpath.HowMany("\\"); - if (y >= z) - { - // Return drive letter only, working path must be absolute? - } - - return ""; - } - - return path; - } - - public static int NumParentDirectories(string path) - { - // determine the number of parent directories in path and return result - int x = path.HowMany('\\'); - return x > 0 ? path.HowMany("..\\") : 0; - } - - public static bool IsRecent(string path) => path == "%recent%"; - - public static string GetLuaPath() - { - return MakeAbsolutePath(Global.Config.PathEntries.LuaPathFragment, null); - } - // Decides if a path is non-empty, not . and not .\ - private static bool PathIsSet(string path) + public static bool PathIsSet(string path) { if (!string.IsNullOrWhiteSpace(path)) { @@ -192,28 +65,6 @@ namespace BizHawk.Client.Common return false; } - public static string GetRomsPath(string sysId) - { - if (Global.Config.UseRecentForRoms) - { - return Environment.SpecialFolder.Recent.ToString(); - } - - var path = Global.Config.PathEntries[sysId, "ROM"]; - - if (path == null || !PathIsSet(path.Path)) - { - path = Global.Config.PathEntries["Global", "ROM"]; - - if (path != null && PathIsSet(path.Path)) - { - return MakeAbsolutePath(path.Path, null); - } - } - - return MakeAbsolutePath(path.Path, sysId); - } - public static string RemoveInvalidFileSystemChars(string name) { var newStr = name; @@ -225,9 +76,9 @@ namespace BizHawk.Client.Common { var filesystemSafeName = game.Name .Replace("|", "+") - .Replace(":", " -") // adelikat - Path.GetFileName scraps everything to the left of a colon unfortunately, so we need this hack here - .Replace("\"", "") // adelikat - Ivan Ironman Stewart's Super Off-Road has quotes in game name - .Replace("/", "+"); // Narry - Mario Bros / Duck hunt has a slash in the name which GetDirectoryName and GetFileName treat as if it were a folder + .Replace(":", " -") // Path.GetFileName scraps everything to the left of a colon unfortunately, so we need this hack here + .Replace("\"", "") // Ivan IronMan Stewart's Super Off-Road has quotes in game name + .Replace("/", "+"); // Mario Bros / Duck hunt has a slash in the name which GetDirectoryName and GetFileName treat as if it were a folder // zero 06-nov-2015 - regarding the below, i changed my mind. for libretro i want subdirectories here. var filesystemDir = Path.GetDirectoryName(filesystemSafeName); @@ -236,7 +87,7 @@ namespace BizHawk.Client.Common filesystemSafeName = RemoveInvalidFileSystemChars(filesystemSafeName); // zero 22-jul-2012 - i don't think this is used the same way it used to. game.Name shouldn't be a path, so this stuff is illogical. - // if game.Name is a path, then someone shouldve made it not-a-path already. + // if game.Name is a path, then someone should have made it not-a-path already. // return Path.Combine(Path.GetDirectoryName(filesystemSafeName), Path.GetFileNameWithoutExtension(filesystemSafeName)); // adelikat: @@ -249,173 +100,6 @@ namespace BizHawk.Client.Common return Path.Combine(filesystemDir, filesystemSafeName); } - public static string SaveRamPath(GameInfo game) - { - var name = FilesystemSafeName(game); - if (Global.MovieSession.Movie.IsActive()) - { - name += $".{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}"; - } - - var pathEntry = Global.Config.PathEntries[game.System, "Save RAM"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return $"{Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name)}.SaveRAM"; - } - - public static string AutoSaveRamPath(GameInfo game) - { - var path = SaveRamPath(game); - return path.Insert(path.Length - 8, ".AutoSaveRAM"); - } - - public static string RetroSaveRAMDirectory(GameInfo game) - { - // hijinx here to get the core name out of the game name - var name = FilesystemSafeName(game); - name = Path.GetDirectoryName(name); - if (name == "") - { - name = FilesystemSafeName(game); - } - - if (Global.MovieSession.Movie.IsActive()) - { - name = Path.Combine(name, $"movie-{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}"); - } - - var pathEntry = Global.Config.PathEntries[game.System, "Save RAM"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name); - } - - public static string RetroSystemPath(GameInfo game) - { - // hijinx here to get the core name out of the game name - var name = FilesystemSafeName(game); - name = Path.GetDirectoryName(name); - if (name == "") - { - name = FilesystemSafeName(game); - } - - var pathEntry = Global.Config.PathEntries[game.System, "System"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name); - } - - public static string GetGameBasePath(GameInfo game) - { - var name = FilesystemSafeName(game); - - var pathEntry = Global.Config.PathEntries[game.System, "Base"]; - return MakeAbsolutePath(pathEntry.Path, game.System); - } - - public static string GetSaveStatePath(GameInfo game) - { - var pathEntry = Global.Config.PathEntries[game.System, "Savestates"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return MakeAbsolutePath(pathEntry.Path, game.System); - } - - public static string SaveStatePrefix(GameInfo game) - { - var name = FilesystemSafeName(game); - - // Neshawk and Quicknes have incompatible savestates, store the name to keep them separate - if (Global.Emulator.SystemId == "NES") - { - name += $".{Global.Emulator.Attributes().CoreName}"; - } - - // Gambatte and GBHawk have incompatible savestates, store the name to keep them separate - if (Global.Emulator.SystemId == "GB") - { - name += $".{Global.Emulator.Attributes().CoreName}"; - } - - if (Global.Emulator is Snes9x) // Keep snes9x savestate away from libsnes, we want to not be too tedious so bsnes names will just have the profile name not the core name - { - name += $".{Global.Emulator.Attributes().CoreName}"; - } - - // Bsnes profiles have incompatible savestates so save the profile name - if (Global.Emulator is LibsnesCore) - { - name += $".{((LibsnesCore)Global.Emulator).CurrentProfile}"; - } - - if (Global.Emulator.SystemId == "GBA") - { - name += $".{Global.Emulator.Attributes().CoreName}"; - } - - if (Global.MovieSession.Movie.IsActive()) - { - name += $".{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}"; - } - - var pathEntry = Global.Config.PathEntries[game.System, "Savestates"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name); - } - - public static string GetCheatsPath(GameInfo game) - { - var pathEntry = Global.Config.PathEntries[game.System, "Cheats"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return MakeAbsolutePath(pathEntry.Path, game.System); - } - - public static string GetPathType(string system, string type) - { - var path = GetPathEntryWithFallback(type, system).Path; - return MakeAbsolutePath(path, system); - } - - public static string ScreenshotPrefix(GameInfo game) - { - var name = FilesystemSafeName(game); - - var pathEntry = Global.Config.PathEntries[game.System, "Screenshots"] ?? - Global.Config.PathEntries[game.System, "Base"]; - - return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name); - } - - /// - /// 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 - /// - public static string TryMakeRelative(string absolutePath, string system = null) - { - var parentPath = string.IsNullOrWhiteSpace(system) - ? GetGlobalBasePathAbsolute() - : MakeAbsolutePath(GetPlatformBase(system), system); -#if true - if (!IsSubfolder(parentPath, absolutePath)) return absolutePath; - - return OSTailoredCode.IsUnixHost - ? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{parentPath}\" \"{absolutePath}\"", $"invalid path {absolutePath} or missing realpath binary") - : absolutePath.Replace(parentPath, "."); -#else // written for Unix port but may be useful for .NET Core - if (!IsSubfolder(parentPath, absolutePath)) - { - return OSTailoredCode.IsUnixHost && parentPath.TrimEnd('.') == $"{absolutePath}/" ? "." : absolutePath; - } - - return OSTailoredCode.IsUnixHost - ? absolutePath.Replace(parentPath.TrimEnd('.'), "./") - : absolutePath.Replace(parentPath, "."); -#endif - } - public static string MakeRelativeTo(string absolutePath, string basePath) { if (IsSubfolder(basePath, absolutePath)) @@ -457,39 +141,5 @@ namespace BizHawk.Client.Common } return false; } - - /// - /// Don't only valid system ids to system ID, pathType is ROM, Screenshot, etc - /// Returns the desired path, if does not exist, returns platform base, else it returns base - /// - private static PathEntry GetPathEntryWithFallback(string pathType, string systemId) - { - var entry = Global.Config.PathEntries[systemId, pathType]; - if (entry == null) - { - entry = Global.Config.PathEntries[systemId, "Base"]; - } - - if (entry == null) - { - entry = Global.Config.PathEntries["Global", "Base"]; - } - - return entry; - } - - /// - /// Puts the currently configured temp path into the environment for use as actual temp directory - /// - public static void RefreshTempPath() - { - if (Global.Config.PathEntries.TempFilesFragment != "") - { - //TODO - BUG - needs to route through PathManager.MakeAbsolutePath or something similar, but how? - string target = Global.Config.PathEntries.TempFilesFragment; - BizHawk.Common.TempFileManager.HelperSetTempPath(target); - } - } } - } diff --git a/BizHawk.Client.Common/SaveSlotManager.cs b/BizHawk.Client.Common/SaveSlotManager.cs index 503c1ed61f..2e4bcdfef7 100644 --- a/BizHawk.Client.Common/SaveSlotManager.cs +++ b/BizHawk.Client.Common/SaveSlotManager.cs @@ -10,12 +10,7 @@ namespace BizHawk.Client.Common private readonly bool[] _slots = new bool[10]; private readonly bool[] _redo = new bool[10]; - public SaveSlotManager() - { - Update(); - } - - public void Update() + public void Update(string saveStatePrefix) { if (Global.Game == null || Global.Emulator == null) { @@ -35,7 +30,7 @@ namespace BizHawk.Client.Common } else { - var file = new FileInfo($"{PathManager.SaveStatePrefix(Global.Game)}.QuickSave{i}.State"); + var file = new FileInfo($"{saveStatePrefix}.QuickSave{i}.State"); if (file.Directory != null && file.Directory.Exists == false) { file.Directory.Create(); @@ -46,7 +41,7 @@ namespace BizHawk.Client.Common } } - public bool HasSlot(int slot) + public bool HasSlot(int slot, string savestatePrefix) { if (!Global.Emulator.HasSavestates()) { @@ -58,7 +53,7 @@ namespace BizHawk.Client.Common return false; } - Update(); + Update(savestatePrefix); return _slots[slot]; } diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index 5951fa4ff2..827a37bf39 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; - +using System.IO; using BizHawk.Common; namespace BizHawk.Client.Common { public class Config { - public static string ControlDefaultPath => PathManager.MakeProgramRelativePath("defctrl.json"); + public static string ControlDefaultPath => Path.Combine(PathManager.GetExeDirectoryAbsolute(), "defctrl.json"); public Config() { @@ -24,7 +24,7 @@ namespace BizHawk.Client.Common { PathEntries.ResolveWithDefaults(); HotkeyBindings.ResolveWithDefaults(); - PathManager.RefreshTempPath(); + PathEntries.RefreshTempPath(); } // Core preference for generic file extension, key: file extension, value: a systemID or empty if no preference @@ -37,9 +37,6 @@ namespace BizHawk.Client.Common [".cue"] = "" }; - // Path Settings ************************************/ - public bool UseRecentForRoms { get; set; } - public string LastRomPath { get; set; } = "."; public PathEntryCollection PathEntries { get; set; } = new PathEntryCollection(); // BIOS Paths diff --git a/BizHawk.Client.Common/config/PathEntry.cs b/BizHawk.Client.Common/config/PathEntry.cs index 129b093265..58526274d7 100644 --- a/BizHawk.Client.Common/config/PathEntry.cs +++ b/BizHawk.Client.Common/config/PathEntry.cs @@ -1,7 +1,4 @@ -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System.Linq; namespace BizHawk.Client.Common { @@ -13,400 +10,9 @@ namespace BizHawk.Client.Common public string System { get; set; } public int Ordinal { get; set; } - public bool HasSystem(string systemID) + internal bool IsSystem(string systemID) { return systemID == System || System.Split('_').Contains(systemID); } } - - [Newtonsoft.Json.JsonObject] - public class PathEntryCollection : IEnumerable - { - public List Paths { get; } - - public PathEntryCollection() - { - Paths = new List(); - Paths.AddRange(DefaultValues); - } - - [Newtonsoft.Json.JsonConstructor] - public PathEntryCollection(List paths) - { - Paths = paths; - } - - public void Add(PathEntry p) - { - Paths.Add(p); - } - - public IEnumerator GetEnumerator() => Paths.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public PathEntry this[string system, string type] => - Paths.FirstOrDefault(p => p.HasSystem(system) && p.Type == type) - ?? TryGetDebugPath(system, type); - - private PathEntry TryGetDebugPath(string system, string type) - { - if (Paths.Any(p => p.HasSystem(system))) - { - // we have the system, but not the type. don't attempt to add an unknown type - return null; - } - - // we don't have anything for the system in question. add a set of stock paths - var systemPath = $"{PathManager.RemoveInvalidFileSystemChars(system)}_INTERIM"; - var systemDisp = $"{system} (INTERIM)"; - - Paths.AddRange(new[] - { - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Base", Path = Path.Combine(".", systemPath), Ordinal = 0 }, - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 } - }); - - return this[system, type]; - } - - public void ResolveWithDefaults() - { - // Add missing entries - foreach (PathEntry defaultPath in DefaultValues) - { - var path = Paths.FirstOrDefault(p => p.System == defaultPath.System && p.Type == defaultPath.Type); - if (path == null) - { - Paths.Add(defaultPath); - } - } - - var entriesToRemove = new List(); - - // Remove entries that no longer exist in defaults - foreach (PathEntry pathEntry in Paths) - { - var path = DefaultValues.FirstOrDefault(p => p.System == pathEntry.System && p.Type == pathEntry.Type); - if (path == null) - { - entriesToRemove.Add(pathEntry); - } - } - - foreach (PathEntry entry in entriesToRemove) - { - Paths.Remove(entry); - } - - // Add missing display names - var missingDisplayPaths = Paths.Where(p => p.SystemDisplayName == null); - foreach (PathEntry path in missingDisplayPaths) - { - path.SystemDisplayName = DefaultValues.First(p => p.System == path.System).SystemDisplayName; - } - } - - private static string ResolveToolsPath(string subPath) - { - if (Path.IsPathRooted(subPath) || subPath.StartsWith("%")) - { - return subPath; - } - - var toolsPath = Global.Config.PathEntries["Global", "Tools"].Path; - - // Hack for backwards compatibility, prior to 1.11.5, .wch files were in .\Tools, we don't want that to turn into .Tools\Tools - if (subPath == "Tools") - { - return toolsPath; - } - - return Path.Combine(toolsPath, subPath); - } - - // Some frequently requested paths, made into a property for convenience - public string ToolsPathFragment => Global.Config.PathEntries["Global", "Tools"].Path; - - public string WatchPathFragment => ResolveToolsPath(Global.Config.PathEntries["Global", "Watch (.wch)"].Path); - - public string MultiDiskBundlesFragment => ResolveToolsPath(Global.Config.PathEntries["Global", "Multi-Disk Bundles"].Path); - - public string LogPathFragment => ResolveToolsPath(Global.Config.PathEntries["Global", "Debug Logs"].Path); - - public string MoviesPathFragment => Global.Config.PathEntries["Global", "Movies"].Path; - - public string MoviesBackupsPathFragment => Global.Config.PathEntries["Global", "Movie backups"].Path; - - public string LuaPathFragment => Global.Config.PathEntries["Global", "Lua"].Path; - - public string FirmwaresPathFragment => Global.Config.PathEntries["Global", "Firmware"].Path; - - public string AvPathFragment => Global.Config.PathEntries["Global", "A/V Dumps"].Path; - - public string GlobalRomFragment => Global.Config.PathEntries["Global", "ROM"].Path; - - public string TempFilesFragment => Global.Config.PathEntries["Global", "Temp Files"].Path; - - // this one is special - public string GlobalBaseFragment => Global.Config.PathEntries["Global", "Base"].Path; - - public static List DefaultValues => new List - { - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Base", Path = ".", Ordinal = 1 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "ROM", Path = ".", Ordinal = 2 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Firmware", Path = Path.Combine(".", "Firmware"), Ordinal = 3 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Movies", Path = Path.Combine(".", "Movies"), Ordinal = 4 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Movie backups", Path = Path.Combine(".", "Movies", "backup"), Ordinal = 5 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "A/V Dumps", Path = ".", Ordinal = 6 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Tools", Path = Path.Combine(".", "Tools"), Ordinal = 7 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Lua", Path = Path.Combine(".", "Lua"), Ordinal = 8 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Watch (.wch)", Path = Path.Combine(".", "."), Ordinal = 9 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Debug Logs", Path = Path.Combine(".", ""), Ordinal = 10 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Macros", Path = Path.Combine(".", "Movies", "Macros"), Ordinal = 11 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "TAStudio states", Path = Path.Combine(".", "Movies", "TAStudio states"), Ordinal = 12 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Multi-Disk Bundles", Path = Path.Combine(".", ""), Ordinal = 13 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "External Tools", Path = Path.Combine(".", "ExternalTools"), Ordinal = 14 }, - new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Temp Files", Path = "", Ordinal = 15 }, - - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Base", Path = Path.Combine(".", "Intellivision"), Ordinal = 0 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, - - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Base", Path = Path.Combine(".", "NES"), Ordinal = 0 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, - - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Base", Path = Path.Combine(".", "SNES"), Ordinal = 0 }, - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Base", Path = Path.Combine(".", "GBA"), Ordinal = 0 }, - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Base", Path = Path.Combine(".", "SMS"), Ordinal = 0 }, - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Base", Path = Path.Combine(".", "Game Gear"), Ordinal = 0 }, - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Base", Path = Path.Combine(".", "SG-1000"), Ordinal = 0 }, - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Base", Path = Path.Combine(".", "Genesis"), Ordinal = 0 }, - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Base", Path = Path.Combine(".", "PC Engine"), Ordinal = 0 }, - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Base", Path = Path.Combine(".", "Gameboy"), Ordinal = 0 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, - - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Base", Path = Path.Combine(".", "Dual Gameboy"), Ordinal = 0 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, - - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Base", Path = Path.Combine(".", "TI83"), Ordinal = 0 }, - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Base", Path = Path.Combine(".", "Atari 2600"), Ordinal = 0 }, - new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Base", Path = Path.Combine(".", "Atari 7800"), Ordinal = 0 }, - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Base", Path = Path.Combine(".", "C64"), Ordinal = 0 }, - new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Base", Path = Path.Combine(".", "ZXSpectrum"), Ordinal = 0 }, - new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Base", Path = Path.Combine(".", "AmstradCPC"), Ordinal = 0 }, - new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Base", Path = Path.Combine(".", "PSX"), Ordinal = 0 }, - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Base", Path = Path.Combine(".", "Coleco"), Ordinal = 0 }, - new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Base", Path = Path.Combine(".", "N64"), Ordinal = 0 }, - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Base", Path = Path.Combine(".", "Saturn"), Ordinal = 0 }, - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Base", Path = Path.Combine(".", "WonderSwan"), Ordinal = 0 }, - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Base", Path = Path.Combine(".", "Lynx"), Ordinal = 0 }, - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Base", Path = Path.Combine(".", "Apple II"), Ordinal = 0 }, - new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Base", Path = Path.Combine(".", "Libretro"), Ordinal = 0 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Cores", Path = Path.Combine(".", "Cores"), Ordinal = 1 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "System", Path = Path.Combine(".", "System"), Ordinal = 2 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 3 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 4 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 5 }, - new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 6 }, - - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Base", Path = Path.Combine(".", "VB"), Ordinal = 0 }, - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Base", Path = Path.Combine(".", "NGP"), Ordinal = 0 }, - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Base", Path = Path.Combine(".", "PCFX"), Ordinal = 0 }, - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Base", Path = Path.Combine(".", "ZXSpectrum"), Ordinal = 0 }, - new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Base", Path = Path.Combine(".", "GB3x"), Ordinal = 0 }, - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Base", Path = Path.Combine(".", "GB4x"), Ordinal = 0 }, - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Base", Path = Path.Combine(".", "VEC"), Ordinal = 0 }, - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Base", Path = Path.Combine(".", "O2"), Ordinal = 0 }, - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Base", Path = Path.Combine(".", "MSX"), Ordinal = 0 }, - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "ROM", Path = ".", Ordinal = 1 }, - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, - new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, - }; - } } diff --git a/BizHawk.Client.Common/config/PathEntryCollection.cs b/BizHawk.Client.Common/config/PathEntryCollection.cs new file mode 100644 index 0000000000..db77c805f5 --- /dev/null +++ b/BizHawk.Client.Common/config/PathEntryCollection.cs @@ -0,0 +1,362 @@ +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json; + +namespace BizHawk.Client.Common +{ + [JsonObject] + public class PathEntryCollection : IEnumerable + { + public List Paths { get; } + + public PathEntryCollection() + { + Paths = new List(); + Paths.AddRange(DefaultValues); + } + + [JsonConstructor] + public PathEntryCollection(List paths) + { + Paths = paths; + } + + public void Add(PathEntry p) + { + Paths.Add(p); + } + + public bool UseRecentForRoms { get; set; } + public string LastRomPath { get; set; } = "."; + + public IEnumerator GetEnumerator() => Paths.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public PathEntry this[string system, string type] => + Paths.FirstOrDefault(p => p.IsSystem(system) && p.Type == type) + ?? TryGetDebugPath(system, type); + + private PathEntry TryGetDebugPath(string system, string type) + { + if (Paths.Any(p => p.IsSystem(system))) + { + // we have the system, but not the type. don't attempt to add an unknown type + return null; + } + + // we don't have anything for the system in question. add a set of stock paths + var systemPath = $"{PathManager.RemoveInvalidFileSystemChars(system)}_INTERIM"; + var systemDisp = $"{system} (INTERIM)"; + + Paths.AddRange(new[] + { + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Base", Path = Path.Combine(".", systemPath), Ordinal = 0 }, + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = system, SystemDisplayName = systemDisp, Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 } + }); + + return this[system, type]; + } + + public void ResolveWithDefaults() + { + // Add missing entries + foreach (PathEntry defaultPath in DefaultValues) + { + var path = Paths.FirstOrDefault(p => p.System == defaultPath.System && p.Type == defaultPath.Type); + if (path == null) + { + Paths.Add(defaultPath); + } + } + + var entriesToRemove = new List(); + + // Remove entries that no longer exist in defaults + foreach (PathEntry pathEntry in Paths) + { + var path = DefaultValues.FirstOrDefault(p => p.System == pathEntry.System && p.Type == pathEntry.Type); + if (path == null) + { + entriesToRemove.Add(pathEntry); + } + } + + foreach (PathEntry entry in entriesToRemove) + { + Paths.Remove(entry); + } + + // Add missing display names + var missingDisplayPaths = Paths.Where(p => p.SystemDisplayName == null); + foreach (PathEntry path in missingDisplayPaths) + { + path.SystemDisplayName = DefaultValues.First(p => p.System == path.System).SystemDisplayName; + } + } + + public string FirmwaresPathFragment => Global.Config.PathEntries["Global", "Firmware"].Path; + + internal string TempFilesFragment => Global.Config.PathEntries["Global", "Temp Files"].Path; + + public static List DefaultValues => new List + { + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Base", Path = ".", Ordinal = 1 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "ROM", Path = ".", Ordinal = 2 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Firmware", Path = Path.Combine(".", "Firmware"), Ordinal = 3 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Movies", Path = Path.Combine(".", "Movies"), Ordinal = 4 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Movie backups", Path = Path.Combine(".", "Movies", "backup"), Ordinal = 5 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "A/V Dumps", Path = ".", Ordinal = 6 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Tools", Path = Path.Combine(".", "Tools"), Ordinal = 7 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Lua", Path = Path.Combine(".", "Lua"), Ordinal = 8 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Watch (.wch)", Path = Path.Combine(".", "."), Ordinal = 9 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Debug Logs", Path = Path.Combine(".", ""), Ordinal = 10 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Macros", Path = Path.Combine(".", "Movies", "Macros"), Ordinal = 11 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "TAStudio states", Path = Path.Combine(".", "Movies", "TAStudio states"), Ordinal = 12 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Multi-Disk Bundles", Path = Path.Combine(".", ""), Ordinal = 13 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "External Tools", Path = Path.Combine(".", "ExternalTools"), Ordinal = 14 }, + new PathEntry { System = "Global_NULL", SystemDisplayName = "Global", Type = "Temp Files", Path = "", Ordinal = 15 }, + + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Base", Path = Path.Combine(".", "Intellivision"), Ordinal = 0 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + new PathEntry { System = "INTV", SystemDisplayName = "Intellivision", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, + + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Base", Path = Path.Combine(".", "NES"), Ordinal = 0 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + new PathEntry { System = "NES", SystemDisplayName = "NES", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, + + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Base", Path = Path.Combine(".", "SNES"), Ordinal = 0 }, + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "SNES_SGB", SystemDisplayName = "SNES", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Base", Path = Path.Combine(".", "GBA"), Ordinal = 0 }, + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GBA", SystemDisplayName = "GBA", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Base", Path = Path.Combine(".", "SMS"), Ordinal = 0 }, + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "SMS", SystemDisplayName = "SMS", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Base", Path = Path.Combine(".", "Game Gear"), Ordinal = 0 }, + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GG", SystemDisplayName = "GG", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Base", Path = Path.Combine(".", "SG-1000"), Ordinal = 0 }, + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "SG", SystemDisplayName = "SG", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Base", Path = Path.Combine(".", "Genesis"), Ordinal = 0 }, + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GEN", SystemDisplayName = "Genesis", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Base", Path = Path.Combine(".", "PC Engine"), Ordinal = 0 }, + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "PCE_PCECD_SGX", SystemDisplayName = "PC Engine", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Base", Path = Path.Combine(".", "Gameboy"), Ordinal = 0 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + new PathEntry { System = "GB_GBC", SystemDisplayName = "Gameboy", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, + + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Base", Path = Path.Combine(".", "Dual Gameboy"), Ordinal = 0 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + new PathEntry { System = "DGB", SystemDisplayName = "Dual Gameboy", Type = "Palettes", Path = Path.Combine(".", "Palettes"), Ordinal = 6 }, + + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Base", Path = Path.Combine(".", "TI83"), Ordinal = 0 }, + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "TI83", SystemDisplayName = "TI83", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Base", Path = Path.Combine(".", "Atari 2600"), Ordinal = 0 }, + new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "A26", SystemDisplayName = "Atari 2600", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Base", Path = Path.Combine(".", "Atari 7800"), Ordinal = 0 }, + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "A78", SystemDisplayName = "Atari 7800", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Base", Path = Path.Combine(".", "C64"), Ordinal = 0 }, + new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "C64", SystemDisplayName = "Commodore 64", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Base", Path = Path.Combine(".", "ZXSpectrum"), Ordinal = 0 }, + new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "ZXSpectrum", SystemDisplayName = "Sinclair ZX Spectrum", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Base", Path = Path.Combine(".", "AmstradCPC"), Ordinal = 0 }, + new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "AmstradCPC", SystemDisplayName = "Amstrad CPC", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Base", Path = Path.Combine(".", "PSX"), Ordinal = 0 }, + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "PSX", SystemDisplayName = "Playstation", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Base", Path = Path.Combine(".", "Coleco"), Ordinal = 0 }, + new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "Coleco", SystemDisplayName = "Coleco", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Base", Path = Path.Combine(".", "N64"), Ordinal = 0 }, + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "N64", SystemDisplayName = "N64", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Base", Path = Path.Combine(".", "Saturn"), Ordinal = 0 }, + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "SAT", SystemDisplayName = "Saturn", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Base", Path = Path.Combine(".", "WonderSwan"), Ordinal = 0 }, + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "WSWAN", SystemDisplayName = "WonderSwan", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Base", Path = Path.Combine(".", "Lynx"), Ordinal = 0 }, + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "Lynx", SystemDisplayName = "Lynx", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Base", Path = Path.Combine(".", "Apple II"), Ordinal = 0 }, + new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "AppleII", SystemDisplayName = "Apple II", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Base", Path = Path.Combine(".", "Libretro"), Ordinal = 0 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Cores", Path = Path.Combine(".", "Cores"), Ordinal = 1 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "System", Path = Path.Combine(".", "System"), Ordinal = 2 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 3 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 4 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 5 }, + new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 6 }, + + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Base", Path = Path.Combine(".", "VB"), Ordinal = 0 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Base", Path = Path.Combine(".", "NGP"), Ordinal = 0 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Base", Path = Path.Combine(".", "PCFX"), Ordinal = 0 }, + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "PCFX", SystemDisplayName = "PCFX", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Base", Path = Path.Combine(".", "ZXSpectrum"), Ordinal = 0 }, + new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "ChannelF", SystemDisplayName = "Fairchild Channel F", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Base", Path = Path.Combine(".", "GB3x"), Ordinal = 0 }, + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GB3x", SystemDisplayName = "GB3x", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Base", Path = Path.Combine(".", "GB4x"), Ordinal = 0 }, + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "GB4x", SystemDisplayName = "GB4x", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Base", Path = Path.Combine(".", "VEC"), Ordinal = 0 }, + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "VEC", SystemDisplayName = "VEC", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Base", Path = Path.Combine(".", "O2"), Ordinal = 0 }, + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "O2", SystemDisplayName = "O2", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Base", Path = Path.Combine(".", "MSX"), Ordinal = 0 }, + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "MSX", SystemDisplayName = "MSX", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + }; + } +} diff --git a/BizHawk.Client.Common/config/PathEntryCollectionExtensions.cs b/BizHawk.Client.Common/config/PathEntryCollectionExtensions.cs new file mode 100644 index 0000000000..4d79d08e75 --- /dev/null +++ b/BizHawk.Client.Common/config/PathEntryCollectionExtensions.cs @@ -0,0 +1,368 @@ +using System; +using System.IO; +using BizHawk.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + public static class PathEntryExtensions + { + /// + /// Returns the base path of the given system. + /// If the system can not be found, an empty string is returned + /// + public static string BaseFor(this PathEntryCollection collection, string systemId) + { + return string.IsNullOrWhiteSpace(systemId) + ? "" + : collection[systemId, "Base"]?.Path ?? ""; + } + + public static string GlobalBaseAbsolutePath(this PathEntryCollection collection) + { + var globalBase = collection["Global", "Base"].Path; + + // if %exe% prefixed then substitute exe path and repeat + if (globalBase.StartsWith("%exe%", StringComparison.InvariantCultureIgnoreCase)) + { + globalBase = PathManager.GetExeDirectoryAbsolute() + globalBase.Substring(5); + } + + // rooted paths get returned without change + // (this is done after keyword substitution to avoid problems though) + if (Path.IsPathRooted(globalBase)) + { + return globalBase; + } + + // not-rooted things are relative to exe path + globalBase = Path.Combine(PathManager.GetExeDirectoryAbsolute(), globalBase); + return globalBase; + } + + /// + /// 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 + /// + public static PathEntry EntryWithFallback(this PathEntryCollection collection, string pathType, string systemId) + { + return (collection[systemId, pathType] + ?? collection[systemId, "Base"]) + ?? collection["Global", "Base"]; + } + + public static string AbsolutePathForType(this PathEntryCollection collection, string systemId, string type) + { + var path = collection.EntryWithFallback(type, systemId).Path; + return collection.AbsolutePathFor(path, systemId); + } + + /// + /// 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 + /// + 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") + { + 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 PathManager.GetExeDirectoryAbsolute() + 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 PathManager.GetExeDirectoryAbsolute(); + } + + public static string MovieAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "Movies"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string MovieBackupsAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "Movie backups"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string AvAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "A/V Dumps"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string LuaAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "Lua"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string FirmwareAbsolutePath(this PathEntryCollection collection) + { + return collection.AbsolutePathFor(collection.FirmwaresPathFragment, null); + } + + public static string LogAbsolutePath(this PathEntryCollection collection) + { + var path = collection.ResolveToolsPath(collection["Global", "Debug Logs"].Path); + return collection.AbsolutePathFor(path, null); + } + + public static string WatchAbsolutePath(this PathEntryCollection collection) + { + var path = collection.ResolveToolsPath(collection["Global", "Watch (.wch)"].Path); + return collection.AbsolutePathFor(path, null); + } + + public static string ToolsAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "Tools"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string TastudioStatesAbsolutePath(this PathEntryCollection collection) + { + var path = collection["Global", "TAStudio states"].Path; + return collection.AbsolutePathFor(path, null); + } + + public static string MultiDiskAbsolutePath(this PathEntryCollection collection) + { + var path = collection.ResolveToolsPath(collection["Global", "Multi-Disk Bundles"].Path); + return collection.AbsolutePathFor(path, null); + } + + public static string RomAbsolutePath(this PathEntryCollection collection, string systemId = null) + { + if (string.IsNullOrWhiteSpace(systemId)) + { + return collection.AbsolutePathFor(collection["Global_NULL", "ROM"].Path, "Global_NULL"); + } + + if (collection.UseRecentForRoms) + { + return Environment.SpecialFolder.Recent.ToString(); + } + + var path = collection[systemId, "ROM"]; + + if (path == null || !PathManager.PathIsSet(path.Path)) + { + path = collection["Global", "ROM"]; + + if (path != null && PathManager.PathIsSet(path.Path)) + { + return collection.AbsolutePathFor(path.Path, null); + } + } + + return collection.AbsolutePathFor(path.Path, systemId); + } + + public static string SaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive) + { + var name = PathManager.FilesystemSafeName(game); + if (movieIsActive) + { + name += $".{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}"; + } + + var pathEntry = collection[game.System, "Save RAM"] + ?? collection[game.System, "Base"]; + + return $"{Path.Combine(collection.AbsolutePathFor(pathEntry.Path, game.System), name)}.SaveRAM"; + } + + // Shenanigans + public static string RetroSaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive, string movieFilename) + { + var name = PathManager.FilesystemSafeName(game); + name = Path.GetDirectoryName(name); + if (name == "") + { + name = PathManager.FilesystemSafeName(game); + } + + if (movieIsActive) + { + name = Path.Combine(name, $"movie-{Path.GetFileNameWithoutExtension(movieFilename)}"); + } + + var pathEntry = collection[game.System, "Save RAM"] + ?? collection[game.System, "Base"]; + + return Path.Combine(collection.AbsolutePathFor(pathEntry.Path, game.System), name); + } + + // Shenanigans + public static string RetroSystemAbsolutePath(this PathEntryCollection collection, GameInfo game) + { + var name = PathManager.FilesystemSafeName(game); + name = Path.GetDirectoryName(name); + if (string.IsNullOrEmpty(name)) + { + name = PathManager.FilesystemSafeName(game); + } + + var pathEntry = collection[game.System, "System"] + ?? collection[game.System, "Base"]; + + return Path.Combine(collection.AbsolutePathFor(pathEntry.Path, game.System), name); + } + + public static string AutoSaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive) + { + var path = collection.SaveRamAbsolutePath(game, movieIsActive); + return path.Insert(path.Length - 8, ".AutoSaveRAM"); + } + + public static string CheatsAbsolutePath(this PathEntryCollection collection, string systemId) + { + var pathEntry = collection[systemId, "Cheats"] + ?? collection[systemId, "Base"]; + + return collection.AbsolutePathFor(pathEntry.Path,systemId); + } + + public static string SaveStateAbsolutePath(this PathEntryCollection collection, string systemId) + { + var pathEntry = collection[systemId, "Savestates"] + ?? collection[systemId, "Base"]; + + return collection.AbsolutePathFor(pathEntry.Path, systemId); + } + + public static string ScreenshotAbsolutePathFor(this PathEntryCollection collection, string systemId) + { + var entry = collection[systemId, "Screenshots"] + ?? collection[systemId, "Base"]; + + return collection.AbsolutePathFor(entry.Path, systemId); + } + + public static string PalettesAbsolutePathFor(this PathEntryCollection collection, string systemId) + { + return collection.AbsolutePathFor(collection[systemId, "Palettes"].Path, systemId); + } + + /// + /// 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 + /// + public static string TryMakeRelative(this PathEntryCollection collection, string absolutePath, string system = null) + { + var parentPath = string.IsNullOrWhiteSpace(system) + ? collection.GlobalBaseAbsolutePath() + : collection.AbsolutePathFor(collection.BaseFor(system), system); +#if true + if (!PathManager.IsSubfolder(parentPath, absolutePath)) return absolutePath; + + return OSTailoredCode.IsUnixHost + ? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{parentPath}\" \"{absolutePath}\"", $"invalid path {absolutePath} or missing realpath binary") + : absolutePath.Replace(parentPath, "."); +#else // written for Unix port but may be useful for .NET Core + if (!IsSubfolder(parentPath, absolutePath)) + { + return OSTailoredCode.IsUnixHost && parentPath.TrimEnd('.') == $"{absolutePath}/" ? "." : absolutePath; + } + + return OSTailoredCode.IsUnixHost + ? absolutePath.Replace(parentPath.TrimEnd('.'), "./") + : absolutePath.Replace(parentPath, "."); +#endif + } + + /// + /// Puts the currently configured temp path into the environment for use as actual temp directory + /// + public static void RefreshTempPath(this PathEntryCollection collection) + { + if (!string.IsNullOrWhiteSpace(collection.TempFilesFragment)) + { + // TODO - BUG - needs to route through PathManager.MakeAbsolutePath or something similar, but how? + string target = collection.TempFilesFragment; + TempFileManager.HelperSetTempPath(target); + } + } + + private static string ResolveToolsPath(this PathEntryCollection collection, string subPath) + { + if (Path.IsPathRooted(subPath) || subPath.StartsWith("%")) + { + return subPath; + } + + var toolsPath = collection["Global", "Tools"].Path; + + // Hack for backwards compatibility, prior to 1.11.5, .wch files were in .\Tools, we don't want that to turn into .Tools\Tools + if (subPath == "Tools") + { + return toolsPath; + } + + return Path.Combine(toolsPath, subPath); + } + } +} diff --git a/BizHawk.Client.Common/lua/LuaFileList.cs b/BizHawk.Client.Common/lua/LuaFileList.cs index 17eef4d737..8bd16ac3b0 100644 --- a/BizHawk.Client.Common/lua/LuaFileList.cs +++ b/BizHawk.Client.Common/lua/LuaFileList.cs @@ -138,7 +138,7 @@ namespace BizHawk.Client.Common sb .Append(file.Enabled ? "1" : "0") .Append(' ') - .Append(PathManager.MakeRelativeTo(PathManager.MakeAbsolutePath(file.Path, ""), + .Append(PathManager.MakeRelativeTo(Global.Config.PathEntries.AbsolutePathFor(file.Path, ""), Path.GetDirectoryName(path))) .AppendLine(); } diff --git a/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs b/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs index 0e07f78920..84676f16ea 100644 --- a/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs +++ b/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs @@ -20,7 +20,7 @@ namespace BizHawk.Client.Common return; } - var backupDir = PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesBackupsPathFragment, null); + var backupDir = Global.Config.PathEntries.MovieBackupsAbsolutePath(); var backupName = Filename; backupName = backupName.Insert(Filename.LastIndexOf("."), $".{DateTime.Now:yyyy-MM-dd HH.mm.ss}"); backupName = Path.Combine(backupDir, Path.GetFileName(backupName)); diff --git a/BizHawk.Client.EmuHawk/AVOut/SynclessRecordingTools.cs b/BizHawk.Client.EmuHawk/AVOut/SynclessRecordingTools.cs index a502825996..74cc3bd490 100644 --- a/BizHawk.Client.EmuHawk/AVOut/SynclessRecordingTools.cs +++ b/BizHawk.Client.EmuHawk/AVOut/SynclessRecordingTools.cs @@ -33,7 +33,7 @@ namespace BizHawk.Client.EmuHawk var ofd = new OpenFileDialog { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}.syncless.txt", - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.AvPathFragment, null) + InitialDirectory = Global.Config.PathEntries.AvAbsolutePath() }; if (ofd.ShowDialog() == DialogResult.Cancel) diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 23724d00ff..0bd03f2970 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -68,57 +68,59 @@ namespace BizHawk.Client.EmuHawk RecentRomSubMenu.DropDownItems.AddRange(Config.RecentRoms.RecentMenu(LoadRomFromRecent, "ROM", romLoading: true)); } + private bool HasSlot(int slot) => _stateSlots.HasSlot(slot, SaveStatePrefix()); + private void SaveStateSubMenu_DropDownOpened(object sender, EventArgs e) { SaveState0MenuItem.Font = new Font( SaveState0MenuItem.Font.FontFamily, SaveState0MenuItem.Font.Size, - _stateSlots.HasSlot(0) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(0) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState1MenuItem.Font = new Font( SaveState1MenuItem.Font.FontFamily, SaveState1MenuItem.Font.Size, - _stateSlots.HasSlot(1) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(1) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState2MenuItem.Font = new Font( SaveState2MenuItem.Font.FontFamily, SaveState2MenuItem.Font.Size, - _stateSlots.HasSlot(2) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(2) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState3MenuItem.Font = new Font( SaveState3MenuItem.Font.FontFamily, SaveState3MenuItem.Font.Size, - _stateSlots.HasSlot(3) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(3) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState4MenuItem.Font = new Font( SaveState4MenuItem.Font.FontFamily, SaveState4MenuItem.Font.Size, - _stateSlots.HasSlot(4) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(4) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState5MenuItem.Font = new Font( SaveState5MenuItem.Font.FontFamily, SaveState5MenuItem.Font.Size, - _stateSlots.HasSlot(5) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(5) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState6MenuItem.Font = new Font( SaveState6MenuItem.Font.FontFamily, SaveState6MenuItem.Font.Size, - _stateSlots.HasSlot(6) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(6) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState7MenuItem.Font = new Font( SaveState7MenuItem.Font.FontFamily, SaveState7MenuItem.Font.Size, - _stateSlots.HasSlot(7) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(7) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState8MenuItem.Font = new Font( SaveState8MenuItem.Font.FontFamily, SaveState8MenuItem.Font.Size, - _stateSlots.HasSlot(8) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(8) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState9MenuItem.Font = new Font( SaveState9MenuItem.Font.FontFamily, SaveState9MenuItem.Font.Size, - _stateSlots.HasSlot(9) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); + HasSlot(9) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular); SaveState1MenuItem.ShortcutKeyDisplayString = Config.HotkeyBindings["Save State 1"].Bindings; SaveState2MenuItem.ShortcutKeyDisplayString = Config.HotkeyBindings["Save State 2"].Bindings; @@ -149,16 +151,16 @@ namespace BizHawk.Client.EmuHawk AutoloadLastSlotMenuItem.Checked = Config.AutoLoadLastSaveSlot; - LoadState1MenuItem.Enabled = _stateSlots.HasSlot(1); - LoadState2MenuItem.Enabled = _stateSlots.HasSlot(2); - LoadState3MenuItem.Enabled = _stateSlots.HasSlot(3); - LoadState4MenuItem.Enabled = _stateSlots.HasSlot(4); - LoadState5MenuItem.Enabled = _stateSlots.HasSlot(5); - LoadState6MenuItem.Enabled = _stateSlots.HasSlot(6); - LoadState7MenuItem.Enabled = _stateSlots.HasSlot(7); - LoadState8MenuItem.Enabled = _stateSlots.HasSlot(8); - LoadState9MenuItem.Enabled = _stateSlots.HasSlot(9); - LoadState0MenuItem.Enabled = _stateSlots.HasSlot(0); + LoadState1MenuItem.Enabled = HasSlot(1); + LoadState2MenuItem.Enabled = HasSlot(2); + LoadState3MenuItem.Enabled = HasSlot(3); + LoadState4MenuItem.Enabled = HasSlot(4); + LoadState5MenuItem.Enabled = HasSlot(5); + LoadState6MenuItem.Enabled = HasSlot(6); + LoadState7MenuItem.Enabled = HasSlot(7); + LoadState8MenuItem.Enabled = HasSlot(8); + LoadState9MenuItem.Enabled = HasSlot(9); + LoadState0MenuItem.Enabled = HasSlot(0); } private void SaveSlotSubMenu_DropDownOpened(object sender, EventArgs e) @@ -352,7 +354,7 @@ namespace BizHawk.Client.EmuHawk /* CLONE OF CODE FROM OpenRom (mostly) */ using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), + InitialDirectory = Config.PathEntries.RomAbsolutePath(Emulator.SystemId), Filter = filter, RestoreDirectory = false, FilterIndex = _lastOpenRomFilter, @@ -366,7 +368,7 @@ namespace BizHawk.Client.EmuHawk } var file = new FileInfo(ofd.FileName); - Config.LastRomPath = file.DirectoryName; + Config.PathEntries.LastRomPath = file.DirectoryName; _lastOpenRomFilter = ofd.FilterIndex; /*************************/ @@ -508,7 +510,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), + InitialDirectory = Config.PathEntries.RomAbsolutePath(Emulator.SystemId), Multiselect = true, Filter = MovieImport.AvailableImporters.ToString("Movie Files"), RestoreDirectory = false @@ -538,7 +540,7 @@ namespace BizHawk.Client.EmuHawk var file = ToolFormBase.SaveFileDialog( filename, - PathManager.MakeAbsolutePath(Config.PathEntries.MoviesPathFragment, null), + Config.PathEntries.MovieAbsolutePath(), "Movie Files", MovieSession.Movie.PreferredExtension); @@ -622,7 +624,7 @@ namespace BizHawk.Client.EmuHawk private void ScreenshotAsMenuItem_Click(object sender, EventArgs e) { - var path = $"{PathManager.ScreenshotPrefix(Game)}.{DateTime.Now:yyyy-MM-dd HH.mm.ss}.png"; + var path = $"{ScreenshotPrefix()}.{DateTime.Now:yyyy-MM-dd HH.mm.ss}.png"; using var sfd = new SaveFileDialog { @@ -1864,7 +1866,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { Filter = new FilesystemFilterSet(new FilesystemFilter("TI-83 Program Files", new[] { "83p", "8xp" })).ToString(), - InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), + InitialDirectory = Config.PathEntries.RomAbsolutePath(Emulator.SystemId), RestoreDirectory = true }; @@ -2796,6 +2798,8 @@ namespace BizHawk.Client.EmuHawk showMenuVisible = true; // I decided this was always possible in chrome-less mode, we'll see what they think } + var movieIsActive = MovieSession.Movie.IsActive(); + ShowMenuContextMenuItem.Visible = ShowMenuContextMenuSeparator.Visible = showMenuVisible; @@ -2814,7 +2818,7 @@ namespace BizHawk.Client.EmuHawk RecordMovieContextMenuItem.Visible = PlayMovieContextMenuItem.Visible = LoadLastMovieContextMenuItem.Visible = - !Emulator.IsNull() && MovieSession.Movie.NotActive(); + !Emulator.IsNull() && !movieIsActive; RestartMovieContextMenuItem.Visible = StopMovieContextMenuItem.Visible = @@ -2822,24 +2826,24 @@ namespace BizHawk.Client.EmuHawk ViewCommentsContextMenuItem.Visible = SaveMovieContextMenuItem.Visible = SaveMovieAsContextMenuItem.Visible = - MovieSession.Movie.IsActive(); + movieIsActive; - BackupMovieContextMenuItem.Visible = MovieSession.Movie.IsActive(); + BackupMovieContextMenuItem.Visible = movieIsActive; - StopNoSaveContextMenuItem.Visible = MovieSession.Movie.IsActive() && MovieSession.Movie.Changes; + StopNoSaveContextMenuItem.Visible = movieIsActive && MovieSession.Movie.Changes; - AddSubtitleContextMenuItem.Visible = !Emulator.IsNull() && MovieSession.Movie.IsActive() && !MovieSession.ReadOnly; + AddSubtitleContextMenuItem.Visible = !Emulator.IsNull() && movieIsActive && !MovieSession.ReadOnly; ConfigContextMenuItem.Visible = _inFullscreen; - ClearSRAMContextMenuItem.Visible = File.Exists(PathManager.SaveRamPath(Game)); + ClearSRAMContextMenuItem.Visible = File.Exists(Config.PathEntries.SaveRamAbsolutePath(Game, movieIsActive)); ContextSeparator_AfterROM.Visible = OpenRomContextMenuItem.Visible || LoadLastRomContextMenuItem.Visible; LoadLastRomContextMenuItem.Enabled = !Config.RecentRoms.Empty; LoadLastMovieContextMenuItem.Enabled = !Config.RecentMovies.Empty; - if (MovieSession.Movie.IsActive()) + if (movieIsActive) { if (MovieSession.ReadOnly) { @@ -2853,7 +2857,7 @@ namespace BizHawk.Client.EmuHawk } } - var file = new FileInfo($"{PathManager.SaveStatePrefix(Game)}.QuickSave{Config.SaveSlot}.State.bak"); + var file = new FileInfo($"{SaveStatePrefix()}.QuickSave{Config.SaveSlot}.State.bak"); if (file.Exists) { @@ -2976,7 +2980,7 @@ namespace BizHawk.Client.EmuHawk private void UndoSavestateContextMenuItem_Click(object sender, EventArgs e) { - _stateSlots.SwapBackupSavestate($"{PathManager.SaveStatePrefix(Game)}.QuickSave{Config.SaveSlot}.State"); + _stateSlots.SwapBackupSavestate($"{SaveStatePrefix()}.QuickSave{Config.SaveSlot}.State"); AddOnScreenMessage($"Save slot {Config.SaveSlot} restored."); } @@ -3026,7 +3030,7 @@ namespace BizHawk.Client.EmuHawk if (e.Button == MouseButtons.Left) { - if (_stateSlots.HasSlot(slot)) + if (HasSlot(slot)) { LoadQuickSave($"QuickSave{slot}"); } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 2305c3ed4e..9c47a64ec1 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -62,6 +62,7 @@ namespace BizHawk.Client.EmuHawk HandleToggleLightAndLink(); SetStatusBar(); + _stateSlots.Update(SaveStatePrefix()); // New version notification UpdateChecker.CheckComplete += (s2, e2) => @@ -1041,9 +1042,16 @@ namespace BizHawk.Client.EmuHawk AddOnScreenMessage("Screenshot (client) saved to clipboard."); } + private string ScreenshotPrefix() + { + var screenPath = Config.PathEntries.ScreenshotAbsolutePathFor(Game.System); + var name = PathManager.FilesystemSafeName(Game); + return Path.Combine(screenPath, name); + } + public void TakeScreenshot() { - var basename = $"{PathManager.ScreenshotPrefix(Game)}.{DateTime.Now:yyyy-MM-dd HH.mm.ss}"; + var basename = $"{ScreenshotPrefix()}.{DateTime.Now:yyyy-MM-dd HH.mm.ss}"; var fnameBare = $"{basename}.png"; var fname = $"{basename} (0).png"; @@ -1405,7 +1413,7 @@ namespace BizHawk.Client.EmuHawk } else { - ofd.InitialDirectory = PathManager.GetPathType("Libretro", "Cores"); + ofd.InitialDirectory = Config.PathEntries.AbsolutePathForType("Libretro", "Cores"); if (!Directory.Exists(ofd.InitialDirectory)) { Directory.CreateDirectory(ofd.InitialDirectory); @@ -1646,10 +1654,11 @@ namespace BizHawk.Client.EmuHawk { try // zero says: this is sort of sketchy... but this is no time for rearchitecting { + var saveRamPath = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie.IsActive()); if (Config.AutosaveSaveRAM) { - var saveram = new FileInfo(PathManager.SaveRamPath(Game)); - var autosave = new FileInfo(PathManager.AutoSaveRamPath(Game)); + var saveram = new FileInfo(saveRamPath); + var autosave = new FileInfo(Config.PathEntries.AutoSaveRamAbsolutePath(Game, MovieSession.Movie.IsActive())); if (autosave.Exists && autosave.LastWriteTime > saveram.LastWriteTime) { AddOnScreenMessage("AutoSaveRAM is newer than last saved SaveRAM"); @@ -1662,7 +1671,7 @@ namespace BizHawk.Client.EmuHawk // GBA vba-next core will try to eat anything, regardless of size if (Emulator is VBANext || Emulator is MGBAHawk || Emulator is NeoGeoPort) { - sram = File.ReadAllBytes(PathManager.SaveRamPath(Game)); + sram = File.ReadAllBytes(saveRamPath); } else { @@ -1677,8 +1686,7 @@ namespace BizHawk.Client.EmuHawk // why do we silently truncate\pad here instead of warning\erroring? sram = new byte[oldRam.Length]; - using var reader = new BinaryReader( - new FileStream(PathManager.SaveRamPath(Game), FileMode.Open, FileAccess.Read)); + using var reader = new BinaryReader(new FileStream(saveRamPath, FileMode.Open, FileAccess.Read)); reader.Read(sram, 0, sram.Length); } @@ -1696,16 +1704,18 @@ namespace BizHawk.Client.EmuHawk { if (Emulator.HasSaveRam()) { + bool movieIsActive = MovieSession.Movie.IsActive(); string path; if (autosave) { - path = PathManager.AutoSaveRamPath(Game); + path = Config.PathEntries.AutoSaveRamAbsolutePath(Game, movieIsActive); AutoFlushSaveRamIn = Config.FlushSaveRamFrames; } else { - path = PathManager.SaveRamPath(Game); + path = Config.PathEntries.SaveRamAbsolutePath(Game, movieIsActive); } + var file = new FileInfo(path); var newPath = $"{path}.new"; var newFile = new FileInfo(newPath); @@ -2116,7 +2126,7 @@ namespace BizHawk.Client.EmuHawk private void SaveSlotSelectedMessage() { int slot = Config.SaveSlot; - string emptyPart = _stateSlots.HasSlot(slot) ? "" : " (empty)"; + string emptyPart = HasSlot(slot) ? "" : " (empty)"; string message = $"Slot {slot}{emptyPart} selected."; AddOnScreenMessage(message); } @@ -2235,7 +2245,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId), + InitialDirectory = Config.PathEntries.RomAbsolutePath(Emulator.SystemId), Filter = RomFilter, RestoreDirectory = false, FilterIndex = _lastOpenRomFilter @@ -2422,7 +2432,7 @@ namespace BizHawk.Client.EmuHawk private Color SlotForeColor(int slot) { - return _stateSlots.HasSlot(slot) + return HasSlot(slot) ? Config.SaveSlot == slot ? SystemColors.HighlightText : SystemColors.WindowText @@ -2438,7 +2448,7 @@ namespace BizHawk.Client.EmuHawk public void UpdateStatusSlots() { - _stateSlots.Update(); + _stateSlots.Update(SaveStatePrefix()); Slot0StatusButton.ForeColor = SlotForeColor(0); Slot1StatusButton.ForeColor = SlotForeColor(1); @@ -3232,12 +3242,12 @@ namespace BizHawk.Client.EmuHawk if (Game != null) { sfd.FileName = $"{PathManager.FilesystemSafeName(Game)}.{ext}"; // don't use Path.ChangeExtension, it might wreck game names with dots in them - sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.AvPathFragment, null); + sfd.InitialDirectory = Config.PathEntries.AvAbsolutePath(); } else { sfd.FileName = "NULL"; - sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.AvPathFragment, null); + sfd.InitialDirectory = Config.PathEntries.AvAbsolutePath(); } sfd.Filter = new FilesystemFilterSet(new FilesystemFilter(ext, new[] { ext })).ToString(); @@ -3455,6 +3465,48 @@ namespace BizHawk.Client.EmuHawk #region Scheduled for refactor + public string SaveStatePrefix() + { + var name = PathManager.FilesystemSafeName(Game); + + // Neshawk and Quicknes have incompatible savestates, store the name to keep them separate + if (Emulator.SystemId == "NES") + { + name += $".{Emulator.Attributes().CoreName}"; + } + + // Gambatte and GBHawk have incompatible savestates, store the name to keep them separate + if (Emulator.SystemId == "GB") + { + name += $".{Emulator.Attributes().CoreName}"; + } + + if (Emulator is Snes9x) // Keep snes9x savestate away from libsnes, we want to not be too tedious so bsnes names will just have the profile name not the core name + { + name += $".{Emulator.Attributes().CoreName}"; + } + + // Bsnes profiles have incompatible savestates so save the profile name + if (Emulator is LibsnesCore bsnes) + { + name += $".{bsnes.CurrentProfile}"; + } + + if (Emulator.SystemId == "GBA") + { + name += $".{Emulator.Attributes().CoreName}"; + } + + if (MovieSession.Movie.IsActive()) + { + name += $".{Path.GetFileNameWithoutExtension(MovieSession.Movie.Filename)}"; + } + + var pathEntry = Config.PathEntries.SaveStateAbsolutePath(Game.System); + + return Path.Combine(pathEntry, name); + } + private void ShowMessageCoreComm(string message) { MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); @@ -3526,7 +3578,7 @@ namespace BizHawk.Client.EmuHawk if (args.OpenAdvanced is OpenAdvanced_OpenRom) { var leftPart = path.Split('|')[0]; - Config.LastRomPath = Path.GetFullPath(Path.GetDirectoryName(leftPart) ?? ""); + Config.PathEntries.LastRomPath = Path.GetFullPath(Path.GetDirectoryName(leftPart) ?? ""); } return true; @@ -3727,11 +3779,12 @@ namespace BizHawk.Client.EmuHawk // Don't load Save Ram if a movie is being loaded if (!MovieSession.MovieIsQueued) { - if (File.Exists(PathManager.SaveRamPath(loader.Game))) + var movieIsActive = MovieSession.Movie.IsActive(); + if (File.Exists(Config.PathEntries.SaveRamAbsolutePath(loader.Game, movieIsActive))) { LoadSaveRam(); } - else if (Config.AutosaveSaveRAM && File.Exists(PathManager.AutoSaveRamPath(loader.Game))) + else if (Config.AutosaveSaveRAM && File.Exists(Config.PathEntries.SaveRamAbsolutePath(loader.Game, movieIsActive))) { AddOnScreenMessage("AutoSaveRAM found, but SaveRAM was not saved"); } @@ -3765,7 +3818,7 @@ namespace BizHawk.Client.EmuHawk RewireSound(); Tools.UpdateCheatRelatedTools(null, null); - if (Config.AutoLoadLastSaveSlot && _stateSlots.HasSlot(Config.SaveSlot)) + if (Config.AutoLoadLastSaveSlot && HasSlot(Config.SaveSlot)) { LoadQuickSave($"QuickSave{Config.SaveSlot}"); } @@ -3843,7 +3896,7 @@ namespace BizHawk.Client.EmuHawk GameIsClosing = true; if (clearSram) { - var path = PathManager.SaveRamPath(Game); + var path = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie.IsActive()); if (File.Exists(path)) { File.Delete(path); @@ -4050,7 +4103,7 @@ namespace BizHawk.Client.EmuHawk return; } - var path = $"{PathManager.SaveStatePrefix(Game)}.{quickSlotName}.State"; + var path = $"{SaveStatePrefix()}.{quickSlotName}.State"; if (!File.Exists(path)) { AddOnScreenMessage($"Unable to load {quickSlotName}.State"); @@ -4116,7 +4169,7 @@ namespace BizHawk.Client.EmuHawk return; } - var path = $"{PathManager.SaveStatePrefix(Game)}.{quickSlotName}.State"; + var path = $"{SaveStatePrefix()}.{quickSlotName}.State"; var file = new FileInfo(path); if (file.Directory != null && !file.Directory.Exists) @@ -4158,7 +4211,7 @@ namespace BizHawk.Client.EmuHawk return; } - var path = PathManager.GetSaveStatePath(Game); + var path = Config.PathEntries.SaveStateAbsolutePath(Game.System); var file = new FileInfo(path); if (file.Directory != null && !file.Directory.Exists) @@ -4172,7 +4225,7 @@ namespace BizHawk.Client.EmuHawk DefaultExt = "State", Filter = new FilesystemFilterSet(FilesystemFilter.EmuHawkSaveStates).ToString(), InitialDirectory = path, - FileName = $"{PathManager.SaveStatePrefix(Game)}.QuickSave0.State" + FileName = $"{SaveStatePrefix()}.QuickSave0.State" }; var result = sfd.ShowHawkDialog(); @@ -4202,7 +4255,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetSaveStatePath(Game), + InitialDirectory = Config.PathEntries.SaveStateAbsolutePath(Game.System), Filter = new FilesystemFilterSet(FilesystemFilter.EmuHawkSaveStates).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs b/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs index 7b7e3253b2..f9eddaa201 100644 --- a/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs +++ b/BizHawk.Client.EmuHawk/config/FirmwaresConfig.cs @@ -274,7 +274,7 @@ namespace BizHawk.Client.EmuHawk else { // lazy substring extraction. really should do a better job - var basePath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null) + Path.DirectorySeparatorChar; + var basePath = _config.PathEntries.FirmwareAbsolutePath() + Path.DirectorySeparatorChar; var path = ri.FilePath.Replace(basePath, ""); @@ -350,7 +350,9 @@ namespace BizHawk.Client.EmuHawk if (ri?.KnownFirmwareFile == null) continue; if (ri.UserSpecified) continue; - string fpTarget = PathManager.StandardFirmwareName(ri.KnownFirmwareFile.RecommendedName); + var fpTarget = Path.Combine( + _config.PathEntries.FirmwareAbsolutePath(), + ri.KnownFirmwareFile.RecommendedName); string fpSource = ri.FilePath; try @@ -369,7 +371,7 @@ namespace BizHawk.Client.EmuHawk private void tbbOpenFolder_Click(object sender, EventArgs e) { - var frmWares = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); + var frmWares = _config.PathEntries.FirmwareAbsolutePath(); if (!Directory.Exists(frmWares)) { Directory.CreateDirectory(frmWares); @@ -405,7 +407,7 @@ namespace BizHawk.Client.EmuHawk InitialDirectory = _currSelectorDir, RestoreDirectory = true }; - string firmwarePath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); + string firmwarePath = _config.PathEntries.FirmwareAbsolutePath(); if (ofd.ShowDialog() == DialogResult.OK) { @@ -589,7 +591,7 @@ namespace BizHawk.Client.EmuHawk private void RefreshBasePath() { string oldBasePath = _currSelectorDir; - linkBasePath.Text = _currSelectorDir = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); + linkBasePath.Text = _currSelectorDir = _config.PathEntries.FirmwareAbsolutePath(); if (oldBasePath != _currSelectorDir) { DoScan(); @@ -653,7 +655,7 @@ namespace BizHawk.Client.EmuHawk private void RunImportJob(IEnumerable files) { bool didSomething = false; - var basePath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); + var basePath = _config.PathEntries.FirmwareAbsolutePath(); string errors = ""; foreach(var f in files) { diff --git a/BizHawk.Client.EmuHawk/config/GB/BmpView.cs b/BizHawk.Client.EmuHawk/config/GB/BmpView.cs index 4d13cd23e7..331bd2c575 100644 --- a/BizHawk.Client.EmuHawk/config/GB/BmpView.cs +++ b/BizHawk.Client.EmuHawk/config/GB/BmpView.cs @@ -91,9 +91,7 @@ namespace BizHawk.Client.EmuHawk public void SaveFile() { - string path = PathManager.MakeAbsolutePath( - Global.Config.PathEntries[Global.Emulator.SystemId, "Screenshots"].Path, - Global.Emulator.SystemId); + string path = Global.Config.PathEntries.ScreenshotAbsolutePathFor(Global.Emulator.SystemId); var di = new DirectoryInfo(path); diff --git a/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs b/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs index 422eedcdef..eb9881e67a 100644 --- a/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs +++ b/BizHawk.Client.EmuHawk/config/GB/ColorChooserForm.cs @@ -308,7 +308,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["GB", "Palettes"].Path, "GB"), + InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("GB"), Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; @@ -344,7 +344,7 @@ namespace BizHawk.Client.EmuHawk { using var sfd = new SaveFileDialog { - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["GB", "Palettes"].Path, "GB"), + InitialDirectory = Global.Config.PathEntries.PalettesAbsolutePathFor("GB"), FileName = $"{Global.Game.Name}.pal", Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true diff --git a/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs b/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs index be5544629f..c144ec1c7d 100644 --- a/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs +++ b/BizHawk.Client.EmuHawk/config/NES/NESGraphicsConfig.cs @@ -55,7 +55,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries["NES", "Palettes"].Path, "NES"), + InitialDirectory = _config.PathEntries.PalettesAbsolutePathFor("NES"), Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs b/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs index 3431e265c4..46d8d6c3bc 100644 --- a/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs +++ b/BizHawk.Client.EmuHawk/config/NES/QuickNesConfig.cs @@ -81,7 +81,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries["NES", "Palettes"].Path, "NES"), + InitialDirectory = _config.PathEntries.PalettesAbsolutePathFor("NES"), Filter = new FilesystemFilterSet(FilesystemFilter.Palettes).ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/config/PathConfig.cs b/BizHawk.Client.EmuHawk/config/PathConfig.cs index 127ec8e7f0..a8885b23bb 100644 --- a/BizHawk.Client.EmuHawk/config/PathConfig.cs +++ b/BizHawk.Client.EmuHawk/config/PathConfig.cs @@ -50,7 +50,7 @@ namespace BizHawk.Client.EmuHawk private void LoadSettings() { - RecentForROMs.Checked = _config.UseRecentForRoms; + RecentForROMs.Checked = _config.PathEntries.UseRecentForRoms; DoTabs(_config.PathEntries.ToList()); SetDefaultFocusedTab(); @@ -208,7 +208,7 @@ namespace BizHawk.Client.EmuHawk PathTabControl.Visible = true; } - private static void BrowseFolder(TextBox box, string name, string system) + private void BrowseFolder(TextBox box, string name, string system) { // Ugly hack, we don't want to pass in the system in for system base and global paths if (name == "Base" || system == "Global" || system == "Global_NULL") @@ -224,7 +224,7 @@ namespace BizHawk.Client.EmuHawk using var f = new FolderBrowserDialog { Description = $"Set the directory for {name}", - SelectedPath = PathManager.MakeAbsolutePath(box.Text, system) + SelectedPath = _config.PathEntries.AbsolutePathFor(box.Text, system) }; result = f.ShowDialog(); selectedPath = f.SelectedPath; @@ -234,20 +234,20 @@ namespace BizHawk.Client.EmuHawk using var f = new FolderBrowserEx { Description = $"Set the directory for {name}", - SelectedPath = PathManager.MakeAbsolutePath(box.Text, system) + SelectedPath = _config.PathEntries.AbsolutePathFor(box.Text, system) }; result = f.ShowDialog(); selectedPath = f.SelectedPath; } - if (result == DialogResult.OK) + if (result.IsOk()) { - box.Text = PathManager.TryMakeRelative(selectedPath, system); + box.Text = _config.PathEntries.TryMakeRelative(selectedPath, system); } } private void SaveSettings() { - _config.UseRecentForRoms = RecentForROMs.Checked; + _config.PathEntries.UseRecentForRoms = RecentForROMs.Checked; foreach (var t in AllPathBoxes) { @@ -325,7 +325,7 @@ namespace BizHawk.Client.EmuHawk { SaveSettings(); - PathManager.RefreshTempPath(); + _config.PathEntries.RefreshTempPath(); _mainForm.AddOnScreenMessage("Path settings saved"); Close(); } diff --git a/BizHawk.Client.EmuHawk/movie/PlayMovie.cs b/BizHawk.Client.EmuHawk/movie/PlayMovie.cs index e497e65b32..69469a8b40 100644 --- a/BizHawk.Client.EmuHawk/movie/PlayMovie.cs +++ b/BizHawk.Client.EmuHawk/movie/PlayMovie.cs @@ -237,7 +237,7 @@ namespace BizHawk.Client.EmuHawk MovieView.VirtualListSize = 0; MovieView.Update(); - var directory = PathManager.MakeAbsolutePath(_config.PathEntries.MoviesPathFragment, null); + var directory = _config.PathEntries.MovieAbsolutePath(); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); @@ -571,7 +571,7 @@ namespace BizHawk.Client.EmuHawk using var ofd = new OpenFileDialog { Filter = new FilesystemFilterSet(FilesystemFilter.BizHawkMovies, FilesystemFilter.TAStudioProjects).ToString(), - InitialDirectory = PathManager.MakeAbsolutePath(_config.PathEntries.MoviesPathFragment, null) + InitialDirectory = _config.PathEntries.MovieAbsolutePath() }; var result = ofd.ShowHawkDialog(); diff --git a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs index 093fc618d7..228773eb5d 100644 --- a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs +++ b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs @@ -64,7 +64,7 @@ namespace BizHawk.Client.EmuHawk path = path.Insert(0, Path.DirectorySeparatorChar.ToString()); } - path = PathManager.MakeAbsolutePath(_config.PathEntries.MoviesPathFragment, null) + path; + path = _config.PathEntries.MovieAbsolutePath() + path; if (!MovieService.MovieExtensions.Contains(Path.GetExtension(path))) { @@ -158,7 +158,7 @@ namespace BizHawk.Client.EmuHawk private void BrowseBtn_Click(object sender, EventArgs e) { - string movieFolderPath = PathManager.MakeAbsolutePath(_config.PathEntries.MoviesPathFragment, null); + string movieFolderPath = _config.PathEntries.MovieAbsolutePath(); // Create movie folder if it doesn't already exist try diff --git a/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs b/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs index b9967509ad..71598d25ea 100644 --- a/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs +++ b/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs @@ -352,7 +352,7 @@ namespace BizHawk.Client.EmuHawk { var file = OpenFileDialog( CurrentFileName, - PathManager.MakeAbsolutePath(Config.PathEntries.ToolsPathFragment, null), + Config.PathEntries.ToolsAbsolutePath(), "Bot files", "bot"); @@ -374,7 +374,7 @@ namespace BizHawk.Client.EmuHawk { var file = SaveFileDialog( CurrentFileName, - PathManager.MakeAbsolutePath(Config.PathEntries.ToolsPathFragment, null), + Config.PathEntries.ToolsAbsolutePath(), "Bot files", "bot"); diff --git a/BizHawk.Client.EmuHawk/tools/CDL.cs b/BizHawk.Client.EmuHawk/tools/CDL.cs index 65da54df43..4343e9c8bf 100644 --- a/BizHawk.Client.EmuHawk/tools/CDL.cs +++ b/BizHawk.Client.EmuHawk/tools/CDL.cs @@ -322,7 +322,7 @@ namespace BizHawk.Client.EmuHawk { var file = OpenFileDialog( _currentFilename, - PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null), + Config.PathEntries.LogAbsolutePath(), "Code Data Logger Files", "cdl"); @@ -371,7 +371,7 @@ namespace BizHawk.Client.EmuHawk { var file = SaveFileDialog( _currentFilename, - PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null), + Config.PathEntries.LogAbsolutePath(), "Code Data Logger Files", "cdl"); @@ -396,9 +396,9 @@ namespace BizHawk.Client.EmuHawk } else { - var file = ToolFormBase.OpenFileDialog( + var file = OpenFileDialog( _currentFilename, - PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null), + Config.PathEntries.LogAbsolutePath(), "Code Data Logger Files", "cdl"); @@ -494,7 +494,7 @@ namespace BizHawk.Client.EmuHawk { _autoloading = true; var autoResumeFile = $"{PathManager.FilesystemSafeName(Global.Game)}.cdl"; - var autoResumeDir = PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null); + var autoResumeDir = Config.PathEntries.LogAbsolutePath(); var autoResumePath = Path.Combine(autoResumeDir, autoResumeFile); if (File.Exists(autoResumePath)) { diff --git a/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs b/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs index 1d0dcb1861..041d62b26d 100644 --- a/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs +++ b/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs @@ -135,11 +135,11 @@ namespace BizHawk.Client.EmuHawk } } - private static bool SaveAs() + private bool SaveAs() { var file = SaveFileDialog( Global.CheatList.CurrentFileName, - PathManager.GetCheatsPath(Global.Game), + Config.PathEntries.CheatsAbsolutePath(Global.Game.System), "Cheat Files", "cht"); @@ -375,7 +375,7 @@ namespace BizHawk.Client.EmuHawk { var file = OpenFileDialog( Global.CheatList.CurrentFileName, - PathManager.GetCheatsPath(Global.Game), + Config.PathEntries.CheatsAbsolutePath(Global.Game.System), "Cheat Files", "cht"); diff --git a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 771eb088e3..a019c46159 100644 --- a/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -1355,7 +1355,7 @@ namespace BizHawk.Client.EmuHawk private void LoadTableFileMenuItem_Click(object sender, EventArgs e) { - string initialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.ToolsPathFragment, null); + string initialDirectory = Config.PathEntries.ToolsAbsolutePath(); var romName = Config.RecentRoms.MostRecent.Contains('|') ? Config.RecentRoms.MostRecent.Split('|').Last() : Config.RecentRoms.MostRecent; diff --git a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index 2fa8cb712e..edd6eb2943 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -243,7 +243,7 @@ namespace BizHawk.Client.EmuHawk _watches.Clear(); foreach (var item in LuaImp.ScriptList.Where(s => !s.IsSeparator)) { - var processedPath = PathManager.TryMakeRelative(item.Path); + var processedPath = Config.PathEntries.TryMakeRelative(item.Path); string pathToLoad = ProcessPath(processedPath); CreateFileWatcher(pathToLoad); @@ -281,7 +281,7 @@ namespace BizHawk.Client.EmuHawk public void LoadLuaFile(string path) { - var processedPath = PathManager.TryMakeRelative(path); + var processedPath = Config.PathEntries.TryMakeRelative(path); var alreadyInSession = LuaImp.ScriptList.Any(t => processedPath == t.Path); if (alreadyInSession) @@ -570,12 +570,12 @@ namespace BizHawk.Client.EmuHawk else if (Global.Game != null) { sfd.FileName = PathManager.FilesystemSafeName(Global.Game); - sfd.InitialDirectory = PathManager.GetLuaPath(); + sfd.InitialDirectory = Config.PathEntries.LuaAbsolutePath(); } else { sfd.FileName = "NULL"; - sfd.InitialDirectory = PathManager.GetLuaPath(); + sfd.InitialDirectory = Config.PathEntries.LuaAbsolutePath(); } sfd.Filter = SessionsFSFilterSet.ToString(); @@ -705,7 +705,7 @@ namespace BizHawk.Client.EmuHawk { var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetLuaPath(), + InitialDirectory = Config.PathEntries.LuaAbsolutePath(), Filter = SessionsFSFilterSet.ToString(), RestoreDirectory = true, Multiselect = false @@ -781,7 +781,7 @@ namespace BizHawk.Client.EmuHawk { InitialDirectory = !string.IsNullOrWhiteSpace(LuaImp.ScriptList.Filename) ? Path.GetDirectoryName(LuaImp.ScriptList.Filename) : - PathManager.MakeAbsolutePath(Config.PathEntries.LuaPathFragment, null), + Config.PathEntries.LuaAbsolutePath(), DefaultExt = ".lua", FileName = !string.IsNullOrWhiteSpace(LuaImp.ScriptList.Filename) ? Path.GetFileNameWithoutExtension(LuaImp.ScriptList.Filename) : @@ -811,7 +811,7 @@ namespace BizHawk.Client.EmuHawk { var ofd = new OpenFileDialog { - InitialDirectory = PathManager.GetLuaPath(), + InitialDirectory = Config.PathEntries.LuaAbsolutePath(), Filter = new FilesystemFilterSet(FilesystemFilter.LuaScripts, FilesystemFilter.TextFiles).ToString(), RestoreDirectory = true, Multiselect = true diff --git a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs index 59d8859d42..05e54f60b5 100644 --- a/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs +++ b/BizHawk.Client.EmuHawk/tools/Macros/MacroInput.cs @@ -277,7 +277,7 @@ namespace BizHawk.Client.EmuHawk private string SuggestedFolder() { - return PathManager.MakeAbsolutePath(Path.Combine( + return Config.PathEntries.AbsolutePathFor(Path.Combine( Config.PathEntries["Global", "Macros"].Path, PathManager.FilesystemSafeName(Global.Game)), null); } diff --git a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs index 78fe092692..7c0fb69e0e 100644 --- a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs +++ b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskBundler.cs @@ -232,7 +232,7 @@ namespace BizHawk.Client.EmuHawk private void BrowseBtn_Click(object sender, EventArgs e) { string filename = ""; - string initialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.MultiDiskBundlesFragment, "Global_NULL"); + string initialDirectory = Config.PathEntries.MultiDiskAbsolutePath(); if (!Global.Game.IsNullInstance()) { diff --git a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskFileSelector.cs b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskFileSelector.cs index 3c43770879..23d8f04b7c 100644 --- a/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskFileSelector.cs +++ b/BizHawk.Client.EmuHawk/tools/MultiDiskBundler/MultiDiskFileSelector.cs @@ -67,7 +67,7 @@ namespace BizHawk.Client.EmuHawk { using var ofd = new OpenFileDialog { - InitialDirectory = PathManager.MakeAbsolutePath(_parent.Config.PathEntries["Global_NULL", "ROM"].Path, "Global_NULL"), + InitialDirectory = _parent.Config.PathEntries.RomAbsolutePath(), Filter = MainForm.RomFilter, RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs index 11bb024f94..3b25288014 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/NameTableViewer.cs @@ -67,12 +67,12 @@ namespace BizHawk.Client.EmuHawk public void Screenshot() { using var sfd = new SaveFileDialog - { - FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Nametables", - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = FilesystemFilterSet.Screenshots.ToString(), - RestoreDirectory = true - }; + { + FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Nametables", + InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), + Filter = FilesystemFilterSet.Screenshots.ToString(), + RestoreDirectory = true + }; var result = sfd.ShowHawkDialog(); if (result != DialogResult.OK) diff --git a/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs index a95d433d2a..43a45ba89a 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/PaletteViewer.cs @@ -73,12 +73,12 @@ namespace BizHawk.Client.EmuHawk public void Screenshot() { var sfd = new SaveFileDialog - { - FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), - Filter = FilesystemFilterSet.Screenshots.ToString(), - RestoreDirectory = true - }; + { + FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", + InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), + Filter = FilesystemFilterSet.Screenshots.ToString(), + RestoreDirectory = true + }; var result = sfd.ShowHawkDialog(); if (result != DialogResult.OK) diff --git a/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs index 61b1d085a3..383667a460 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/PatternViewer.cs @@ -37,7 +37,7 @@ namespace BizHawk.Client.EmuHawk var sfd = new SaveFileDialog { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Patterns", - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), + InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs b/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs index 77638853ec..5ff4f746d4 100644 --- a/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/NES/SpriteViewer.cs @@ -39,7 +39,7 @@ namespace BizHawk.Client.EmuHawk var sfd = new SaveFileDialog { FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Sprites", - InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Screenshots"].Path, "NES"), + InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), Filter = FilesystemFilterSet.Screenshots.ToString(), RestoreDirectory = true }; diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs index 7561afc487..50c54b53a1 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs @@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk var ofd = new OpenFileDialog { FileName = filename, - InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.MoviesPathFragment, null), + InitialDirectory = Config.PathEntries.MovieAbsolutePath(), Filter = new FilesystemFilterSet( new FilesystemFilter("All Available Files", MovieService.MovieExtensions.Reverse().ToArray()), FilesystemFilter.TAStudioProjects, diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 617365c6cd..a03aa0f3be 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -21,7 +21,7 @@ namespace BizHawk.Client.EmuHawk public TasMovie CurrentTasMovie => Global.MovieSession.Movie as TasMovie; public bool IsInMenuLoop { get; private set; } - public string StatesPath => PathManager.MakeAbsolutePath(Config.PathEntries["Global", "TAStudio states"].Path, null); + public string StatesPath => Config.PathEntries.TastudioStatesAbsolutePath(); private readonly List _tasClipboard = new List(); private const string CursorColumnName = "CursorColumn"; @@ -855,7 +855,7 @@ namespace BizHawk.Client.EmuHawk private static string DefaultTasProjName() { return Path.Combine( - PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null), + Global.Config.PathEntries.MovieAbsolutePath(), $"{TasMovie.DefaultProjectName}.{TasMovie.Extension}"); } @@ -865,7 +865,7 @@ namespace BizHawk.Client.EmuHawk private static string SuggestedTasProjName() { return Path.Combine( - PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null), + Global.Config.PathEntries.MovieAbsolutePath(), $"{PathManager.FilesystemSafeName(Global.Game)}.{TasMovie.Extension}"); } @@ -909,7 +909,7 @@ namespace BizHawk.Client.EmuHawk var file = SaveFileDialog( filename, - PathManager.MakeAbsolutePath(Config.PathEntries.MoviesPathFragment, null), + Global.Config.PathEntries.MovieAbsolutePath(), "Tas Project Files", "tasproj"); diff --git a/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs b/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs index dfc595272f..d61528bd89 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolFormBase.cs @@ -67,14 +67,14 @@ namespace BizHawk.Client.EmuHawk return new FileInfo(sfd.FileName); } - public static FileInfo GetWatchFileFromUser(string currentFile) + public FileInfo GetWatchFileFromUser(string currentFile) { - return OpenFileDialog(currentFile, PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPathFragment, null), "Watch Files", "wch"); + return OpenFileDialog(currentFile, Config.PathEntries.WatchAbsolutePath(), "Watch Files", "wch"); } - public static FileInfo GetWatchSaveFileFromUser(string currentFile) + public FileInfo GetWatchSaveFileFromUser(string currentFile) { - return SaveFileDialog(currentFile, PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPathFragment, null), "Watch Files", "wch"); + return SaveFileDialog(currentFile, Config.PathEntries.WatchAbsolutePath(), "Watch Files", "wch"); } public void ViewInHexEditor(MemoryDomain domain, IEnumerable addresses, WatchSize size) diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 3f61756b52..3536c76e0c 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -865,7 +865,7 @@ namespace BizHawk.Client.EmuHawk var pathEntry = _config.PathEntries[Global.Game.System, "Cheats"] ?? _config.PathEntries[Global.Game.System, "Base"]; - var path = PathManager.MakeAbsolutePath(pathEntry.Path, Global.Game.System); + var path = _config.PathEntries.AbsolutePathFor(pathEntry.Path, Global.Game.System); var f = new FileInfo(path); if (f.Directory != null && f.Directory.Exists == false) diff --git a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs index 3dbe7daaff..b46d7062c4 100644 --- a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs +++ b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs @@ -285,7 +285,7 @@ namespace BizHawk.Client.EmuHawk if (LogFile == null) { sfd.FileName = PathManager.FilesystemSafeName(Global.Game) + _extension; - sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null); + sfd.InitialDirectory = Config.PathEntries.LogAbsolutePath(); } else if (!string.IsNullOrWhiteSpace(LogFile.FullName)) { @@ -295,7 +295,7 @@ namespace BizHawk.Client.EmuHawk else { sfd.FileName = Path.GetFileNameWithoutExtension(LogFile.FullName); - sfd.InitialDirectory = PathManager.MakeAbsolutePath(Config.PathEntries.LogPathFragment, null); + sfd.InitialDirectory = Config.PathEntries.LogAbsolutePath(); } sfd.Filter = new FilesystemFilterSet( @@ -458,7 +458,7 @@ namespace BizHawk.Client.EmuHawk FileBox.Visible = true; BrowseBox.Visible = true; var name = PathManager.FilesystemSafeName(Global.Game); - var filename = Path.Combine(PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), name) + _extension; + var filename = Path.Combine(Config.PathEntries.LogAbsolutePath(), name) + _extension; LogFile = new FileInfo(filename); if (LogFile.Directory != null && !LogFile.Directory.Exists) { diff --git a/BizHawk.Common/TempFileManager.cs b/BizHawk.Common/TempFileManager.cs index 96edbe9ec3..ef8a329e35 100644 --- a/BizHawk.Common/TempFileManager.cs +++ b/BizHawk.Common/TempFileManager.cs @@ -124,7 +124,7 @@ namespace BizHawk.Common public static void HelperSetTempPath(string path) { - //yes... this is how we're doing it, for now, until it's proven to be troublesome + // yes... this is how we're doing it, for now, until it's proven to be troublesome Directory.CreateDirectory(path); Environment.SetEnvironmentVariable("TMP", path); Environment.SetEnvironmentVariable("TEMP", path);