diff --git a/src/core/system.cpp b/src/core/system.cpp index d4470a03a..94835c047 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -7,6 +7,7 @@ #include "common/file_system.h" #include "common/iso_reader.h" #include "common/log.h" +#include "common/make_array.h" #include "common/state_wrapper.h" #include "common/string_util.h" #include "common/timestamp.h" @@ -279,6 +280,26 @@ bool IsM3UFileName(const char* path) return (extension && StringUtil::Strcasecmp(extension, ".m3u") == 0); } +bool IsLoadableFilename(const char* path) +{ + static constexpr auto extensions = make_array(".bin", ".cue", ".img", ".iso", ".chd", // discs + ".exe", ".psexe", // exes + ".psf", ".minipsf", // psf + ".m3u" // playlists + ); + const char* extension = std::strrchr(path, '.'); + if (!extension) + return false; + + for (const char* test_extension : extensions) + { + if (StringUtil::Strcasecmp(extension, test_extension) == 0) + return true; + } + + return false; +} + std::vector ParseM3UFile(const char* path) { std::ifstream ifs(path); diff --git a/src/core/system.h b/src/core/system.h index 9c1098e3e..daad15838 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -66,6 +66,9 @@ bool IsPsfFileName(const char* path); /// Returns true if the filename is a M3U Playlist we can handle. bool IsM3UFileName(const char* path); +/// Returns true if the filename is one we can load. +bool IsLoadableFilename(const char* path); + /// Parses an M3U playlist, returning the entries. std::vector ParseM3UFile(const char* path); diff --git a/src/frontend-common/game_list.cpp b/src/frontend-common/game_list.cpp index 3389be33b..2849d8418 100644 --- a/src/frontend-common/game_list.cpp +++ b/src/frontend-common/game_list.cpp @@ -52,6 +52,16 @@ const char* GameList::GetGameListCompatibilityRatingString(GameListCompatibility ""; } +bool GameList::IsScannableFilename(const std::string& path) +{ + // we don't scan bin files because they'll duplicate + std::string::size_type pos = path.rfind('.'); + if (pos != std::string::npos && StringUtil::Strcasecmp(path.c_str() + pos, ".bin") == 0) + return false; + + return System::IsLoadableFilename(path.c_str()); +} + bool GameList::GetExeListEntry(const char* path, GameListEntry* entry) { FILESYSTEM_STAT_DATA ffd; @@ -499,24 +509,8 @@ void GameList::ScanDirectory(const char* path, bool recursive, ProgressCallback* for (const FILESYSTEM_FIND_DATA& ffd : files) { progress->IncrementProgressValue(); - - // if this is a .bin, check if we have a .cue. if there is one, skip it - const char* extension = std::strrchr(ffd.FileName.c_str(), '.'); - if (extension && StringUtil::Strcasecmp(extension, ".bin") == 0) - { -#if 0 - std::string temp(ffd.FileName, extension - ffd.FileName); - temp += ".cue"; - if (std::any_of(files.begin(), files.end(), - [&temp](const FILESYSTEM_FIND_DATA& it) { return StringUtil::Strcasecmp(it.FileName, temp.c_str()) == 0; })) - { - Log_DebugPrintf("Skipping due to '%s' existing", temp.c_str()); - continue; - } -#else + if (!IsScannableFilename(ffd.FileName)) continue; -#endif - } std::string entry_path(ffd.FileName); if (std::any_of(m_entries.begin(), m_entries.end(), diff --git a/src/frontend-common/game_list.h b/src/frontend-common/game_list.h index 490370cc2..30946d5c4 100644 --- a/src/frontend-common/game_list.h +++ b/src/frontend-common/game_list.h @@ -94,6 +94,8 @@ public: /// Returns a string representation of a compatibility level. static const char* GetGameListCompatibilityRatingString(GameListCompatibilityRating rating); + static bool IsScannableFilename(const std::string& path); + const EntryList& GetEntries() const { return m_entries; } const u32 GetEntryCount() const { return static_cast(m_entries.size()); } const std::vector& GetSearchDirectories() const { return m_search_directories; }