diff --git a/src/BizHawk.Client.Common/RomGame.cs b/src/BizHawk.Client.Common/RomGame.cs index ee94c2a899..a96cfa9f9f 100644 --- a/src/BizHawk.Client.Common/RomGame.cs +++ b/src/BizHawk.Client.Common/RomGame.cs @@ -29,7 +29,7 @@ namespace BizHawk.Client.Common throw new Exception("The file needs to exist, yo."); } - Extension = file.Extension; + Extension = file.Extension.ToUpperInvariant(); var stream = file.GetStream(); int fileLength = (int)stream.Length; @@ -63,8 +63,8 @@ namespace BizHawk.Client.Common { RomData = FileData; } - else if (file.Extension == ".DSK" || file.Extension == ".TAP" || file.Extension == ".TZX" || - file.Extension == ".PZX" || file.Extension == ".CSW" || file.Extension == ".WAV" || file.Extension == ".CDT") + else if (file.Extension == ".dsk" || file.Extension == ".tap" || file.Extension == ".tzx" || + file.Extension == ".pzx" || file.Extension == ".csw" || file.Extension == ".wav" || file.Extension == ".cdt") { // these are not roms. unfortunately if treated as such there are certain edge-cases // where a header offset is detected. This should mitigate this issue until a cleaner solution is found @@ -79,12 +79,12 @@ namespace BizHawk.Client.Common Buffer.BlockCopy(FileData, headerOffset, RomData, 0, romLength); } - if (file.Extension == ".SMD") + if (file.Extension == ".smd") { RomData = DeInterleaveSMD(RomData); } - if (file.Extension == ".Z64" || file.Extension == ".N64" || file.Extension == ".V64") + if (file.Extension == ".z64" || file.Extension == ".n64" || file.Extension == ".v64") { RomData = MutateSwapN64(RomData); } @@ -92,7 +92,7 @@ namespace BizHawk.Client.Common // note: this will be taking several hashes, of a potentially large amount of data.. yikes! GameInfo = Database.GetGameInfo(RomData, file.Name); - if (GameInfo.NotInDatabase && headerOffset == 128 && file.Extension == ".A78") + if (GameInfo.NotInDatabase && headerOffset == 128 && file.Extension == ".a78") { // if the game is not in the DB, add the header back in so the core can use it // for now only .A78 games, but probably should be for other systems as well @@ -104,7 +104,7 @@ namespace BizHawk.Client.Common if (patch != null) { using var patchFile = new HawkFile(patch); - patchFile.BindFirstOf("IPS"); + patchFile.BindFirstOf(".ips"); if (patchFile.IsBound) { RomData = IPS.Patch(RomData, patchFile.GetStream()); diff --git a/src/BizHawk.Client.Common/RomLoader.cs b/src/BizHawk.Client.Common/RomLoader.cs index 7ea52b0857..7c9dde5edb 100644 --- a/src/BizHawk.Client.Common/RomLoader.cs +++ b/src/BizHawk.Client.Common/RomLoader.cs @@ -208,9 +208,9 @@ namespace BizHawk.Client.Common { var romExtensions = new[] { - "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", - "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", - "V64", "N64", "WS", "WSC", "GBA", "32X", "VEC", "O2" + ".sms", ".smc", ".sfc", ".pce", ".sgx", ".gg", ".sg", ".bin", ".gen", ".md", ".smd", ".gb", + ".nes", ".fds", ".rom", ".int", ".gbc", ".unf", ".a78", ".crt", ".col", ".xml", ".z64", + ".v64", ".n64", ".ws", ".wsc", ".gba", ".32x", ".vec", ".o2" }; // try binding normal rom extensions first @@ -426,11 +426,11 @@ namespace BizHawk.Client.Common rom = new RomGame(file); // hacky for now - if (file.Extension.ToLowerInvariant() == ".exe") + if (file.Extension == ".exe") { rom.GameInfo.System = "PSX"; } - else if (file.Extension.ToLowerInvariant() == ".nsf") + else if (file.Extension == ".nsf") { rom.GameInfo.System = "NES"; } @@ -685,7 +685,7 @@ namespace BizHawk.Client.Common } // not libretro: do extension checking - var ext = file.Extension.ToLowerInvariant(); + var ext = file.Extension; switch (ext) { case ".m3u": diff --git a/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs b/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs index 773e6424f5..7b26e38c9a 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs @@ -81,7 +81,7 @@ namespace BizHawk.Client.EmuHawk //try acquiring file using (var hf = new HawkFile(fn)) { - using (var exe = hf.BindFirstOf("EXE")) + using (var exe = hf.BindFirstOf(".exe")) { var data = exe.ReadAllBytes(); diff --git a/src/BizHawk.Common/HawkFile/HawkFile.cs b/src/BizHawk.Common/HawkFile/HawkFile.cs index 2af5e4f417..3736b32ebb 100644 --- a/src/BizHawk.Common/HawkFile/HawkFile.cs +++ b/src/BizHawk.Common/HawkFile/HawkFile.cs @@ -4,8 +4,6 @@ using System.Diagnostics; using System.IO; using System.Linq; -using BizHawk.Common.StringExtensions; - namespace BizHawk.Common { /// @@ -54,8 +52,8 @@ namespace BizHawk.Common /// true if a file is bound and the bound file exists public readonly bool Exists; - /// returns the extension of Name in uppercase - public string Extension => Path.GetExtension(Name).ToUpperInvariant(); + /// the file extension (of ); including the leading period and in lowercase + public string Extension => Path.GetExtension(Name).ToLowerInvariant(); /// returns the complete full path of the bound file, excluding the archive member portion public readonly string FullPathWithoutMember; @@ -175,20 +173,18 @@ namespace BizHawk.Common return ai == null ? null : BindArchiveMember(ai.Value); } + /// File extensions; include the leading period in each, and use lowercase. /// stream already bound - private HawkFile BindByExtensionCore(bool first, params string[] extensions) + private HawkFile BindByExtensionCore(string[] extensions, bool onlyBindSingle = false) { if (!_rootExists) return this; if (_boundStream != null) throw new InvalidOperationException("stream already bound!"); - - if(extensions.Any(e=>e.StartsWith("."))) - throw new InvalidOperationException("for this purpose extension should not start with a dot"); if (_archiveItems == null || _extractor == null) { // open uncompressed file if (extensions.Length == 0 - || Path.GetExtension(FullPathWithoutMember).Substring(1).In(extensions)) + || extensions.Contains(Path.GetExtension(FullPathWithoutMember).ToLowerInvariant())) { BindRoot(); } @@ -197,10 +193,10 @@ namespace BizHawk.Common { if (extensions.Length != 0) { - var candidates = _archiveItems.Where(item => Path.GetExtension(item.Name).Substring(1).In(extensions)).ToList(); - if (candidates.Count != 0 && first || candidates.Count == 1) BindArchiveMember(candidates[0].Index); + var candidates = _archiveItems.Where(item => extensions.Contains(Path.GetExtension(item.Name).ToLowerInvariant())).ToList(); + if (onlyBindSingle ? candidates.Count == 1 : candidates.Count != 0) BindArchiveMember(candidates[0].Index); } - else if (first || _archiveItems.Count == 1) + else if (!onlyBindSingle || _archiveItems.Count == 1) { BindArchiveMember(0); } @@ -209,12 +205,24 @@ namespace BizHawk.Common return this; } - /// Binds the first item in the archive (or the file itself), assuming that there is anything in the archive. - public HawkFile BindFirst() => BindFirstOf(); + /// Binds the first archive member if one exists, or for non-archives, binds the file. + public HawkFile BindFirst() => BindByExtensionCore(Array.Empty()); - /// Binds the first item in the archive (or the file itself) if the extension matches one of the supplied templates. + /// + /// Binds the first archive member whose file extension is in if one exists, + /// or for non-archives, binds the file if its file extension is in . + /// + /// File extensions; include the leading period in each, and use lowercase. /// You probably should use or the archive chooser instead. - public HawkFile BindFirstOf(params string[] extensions) => BindByExtensionCore(true, extensions); + public HawkFile BindFirstOf(string[] extensions) => BindByExtensionCore(extensions); + + /// + /// Binds the first archive member whose file extension is if one exists, + /// or for non-archives, binds the file if its file extension is . + /// + /// File extension; include the leading period, and use lowercase. + /// You probably should use or the archive chooser instead. + public HawkFile BindFirstOf(string extension) => BindByExtensionCore(new[] { extension }); /// causes the root to be bound (in the case of non-archive files) private void BindRoot() @@ -223,8 +231,9 @@ namespace BizHawk.Common Debug.WriteLine($"{nameof(HawkFile)} bound {CanonicalFullPath}"); } - /// binds one of the supplied extensions if there is only one match in the archive - public HawkFile BindSoleItemOf(params string[] extensions) => BindByExtensionCore(false, extensions); + /// As , but doesn't bind anything if there are multiple archive members with a matching file extension. + /// File extensions; include the leading period in each, and use lowercase. + public HawkFile BindSoleItemOf(string[] extensions) => BindByExtensionCore(extensions, onlyBindSingle: true); public void Dispose() {