From ea40afb30a68b381ed9ab9037a5e07c1d613f697 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Mon, 20 Jan 2025 16:48:03 +0100 Subject: [PATCH] FileFilder: Make wildcard processing an option Add (Sim) RPG Maker 95 to detection --- .../player/game_browser/ProjectType.java | 18 +++--- src/directory_tree.cpp | 6 +- src/directory_tree.h | 23 ++++--- src/filefinder.cpp | 20 +++++- src/filefinder.h | 64 ++++++++----------- src/scene_gamebrowser.cpp | 24 +++---- src/window_gamelist.cpp | 3 +- 7 files changed, 86 insertions(+), 72 deletions(-) diff --git a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/ProjectType.java b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/ProjectType.java index 28b73005f9..29f01d93f8 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/ProjectType.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/ProjectType.java @@ -5,14 +5,16 @@ import org.easyrpg.player.R; public enum ProjectType { - UNKNOWN("Unknown") - , SUPPORTED("Supported") - , RPG_MAKER_XP("RPG Maker XP") - , RPG_MAKER_VX("RPG Maker VX") - , RPG_MAKER_VX_ACE("RPG Maker VX Ace") - , RPG_MAKER_MV_MZ("RPG Maker MV/MZ") - , WOLF_RPG_EDITOR("Wolf RPG Editor") - , ENCRYPTED_2K3_MANIACS("Encrypted 2k3 (Maniacs Patch)"); + UNKNOWN("Unknown"), + SUPPORTED("Supported"), + RPG_MAKER_XP("RPG Maker XP"), + RPG_MAKER_VX("RPG Maker VX"), + RPG_MAKER_VX_ACE("RPG Maker VX Ace"), + RPG_MAKER_MV_MZ("RPG Maker MV/MZ"), + WOLF_RPG_EDITOR("Wolf RPG Editor"), + ENCRYPTED_2K3_MANIACS("Encrypted 2k3 (Maniacs Patch)"), + RPG_MAKER_95("RPG Maker 95"), + SIM_RPG_MAKER_95("Sim RPG Maker 95"); private final String label; diff --git a/src/directory_tree.cpp b/src/directory_tree.cpp index 1135165a7b..d20f4b12b9 100644 --- a/src/directory_tree.cpp +++ b/src/directory_tree.cpp @@ -223,12 +223,12 @@ std::string DirectoryTree::FindFile(const DirectoryTree::Args& args) const { } std::string dir_key = make_key(dir); - auto dir_it = Find(dir_cache, dir_key); + auto dir_it = Find(dir_cache, dir_key, args.process_wildcards); assert(dir_it != dir_cache.end()); std::string name_key = make_key(name); if (args.exts.empty()) { - auto entry_it = Find(*entries, name_key); + auto entry_it = Find(*entries, name_key, args.process_wildcards); if (entry_it != entries->end() && entry_it->second.type == FileType::Regular) { auto full_path = FileFinder::MakePath(dir_it->second, entry_it->second.name); DebugLog("FindFile Found: {} | {} | {}", dir, name, full_path); @@ -237,7 +237,7 @@ std::string DirectoryTree::FindFile(const DirectoryTree::Args& args) const { } else { for (const auto& ext : args.exts) { auto full_name_key = name_key + ToString(ext); - auto entry_it = Find(*entries, full_name_key); + auto entry_it = Find(*entries, full_name_key, args.process_wildcards); if (entry_it != entries->end() && entry_it->second.type == FileType::Regular) { auto full_path = FileFinder::MakePath(dir_it->second, entry_it->second.name); DebugLog("FindFile Found: {} | {} | {}", dir, name, full_path); diff --git a/src/directory_tree.h b/src/directory_tree.h index 7e7e23debf..b5d7959846 100644 --- a/src/directory_tree.h +++ b/src/directory_tree.h @@ -73,6 +73,10 @@ class DirectoryTree { * Off by default because file probing would spam the terminal alot. */ bool file_not_found_warning = false; + /** + * Processes ? in filenames as placeholders + */ + bool process_wildcards = false; }; using DirectoryListType = std::vector>; @@ -148,9 +152,9 @@ class DirectoryTree { static bool WildcardMatch(const StringView& pattern, const StringView& text); template - auto Find(T& cache, StringView what) const { - // No wildcard - binary search - if (what.find('?') == StringView::npos) { + auto Find(T& cache, StringView what, bool process_wildcards = false) const { + if (!process_wildcards) { + // No wildcard - binary search auto it = std::lower_bound(cache.begin(), cache.end(), what, [](const auto& e, const auto& w) { return e.first < w; }); @@ -158,14 +162,15 @@ class DirectoryTree { return it; } return cache.end(); - } - - // Has wildcard - linear search - for (auto it = cache.begin(); it != cache.end(); ++it) { - if (WildcardMatch(what, it->first)) { - return it; + } else { + // Has wildcard - linear search + for (auto it = cache.begin(); it != cache.end(); ++it) { + if (WildcardMatch(what, it->first)) { + return it; + } } } + return cache.end(); } diff --git a/src/filefinder.cpp b/src/filefinder.cpp index d8f65f499f..55b8c920ea 100644 --- a/src/filefinder.cpp +++ b/src/filefinder.cpp @@ -317,15 +317,21 @@ FileFinder::ProjectType FileFinder::GetProjectType(const FilesystemView &fs) { return FileFinder::ProjectType::Supported; } - if (!fs.FindFile("RGSS10??.dll").empty()) { + DirectoryTree::Args args; + args.process_wildcards = true; + args.path = "RGSS10??.dll"; + + if (!fs.FindFile(args).empty()) { return FileFinder::ProjectType::RpgMakerXp; } - if (!fs.FindFile("RGSS20??.dll").empty()) { + args.path = "RGSS20??.dll"; + if (!fs.FindFile(args).empty()) { return FileFinder::ProjectType::RpgMakerVx; } - if (!fs.FindFile("System", "RGSS30?.dll").empty()) { + args.path = "System/RGSS30?.dll"; + if (!fs.FindFile(args).empty()) { return FileFinder::ProjectType::RpgMakerVxAce; } @@ -341,6 +347,14 @@ FileFinder::ProjectType FileFinder::GetProjectType(const FilesystemView &fs) { return FileFinder::ProjectType::Encrypted2k3Maniacs; } + if (!fs.FindFile("Game.RPG").empty()) { + return FileFinder::ProjectType::RpgMaker95; + } + + if (!fs.FindFile("Game.DAT").empty()) { + return FileFinder::ProjectType::SimRpgMaker95; + } + return FileFinder::ProjectType::Unknown; } diff --git a/src/filefinder.h b/src/filefinder.h index 204ba9b3c8..7e5e3a0651 100644 --- a/src/filefinder.h +++ b/src/filefinder.h @@ -25,6 +25,7 @@ #include "string_view.h" #include "directory_tree.h" +#include #include #include #include @@ -60,8 +61,23 @@ namespace FileFinder { RpgMakerMvMz, WolfRpgEditor, Encrypted2k3Maniacs, + RpgMaker95, + SimRpgMaker95 }; + constexpr auto kProjectType = lcf::makeEnumTags( + "Unknown", + "Supported", + "RPG Maker XP", + "RPG Maker VX", + "RPG Maker VX Ace", + "RPG Maker MV/MZ", + "Wolf RPG Editor", + "Encrypted 2k3MP", + "RPG Maker 95", + "Sim RPG Maker 95" + ); + /** * Helper struct combining the project's directory and its type. */ @@ -70,9 +86,6 @@ namespace FileFinder { ProjectType type; }; - /** @return Human readable project type label */ - static const char* GetProjectTypeLabel(ProjectType pt); - /** * Quits FileFinder. */ @@ -356,18 +369,18 @@ namespace FileFinder { bool IsMajorUpdatedTree(); /** RPG_RT.exe file size thresholds - * - * 2k v1.51 (Japanese) : 746496 - * 2k v1.50 (Japanese) : 745984 - * -- threshold (2k) -- : 735000 - * 2k v1.10 (Japanese) : 726016 - * - * 2k3 v1.09a (Japanese) : 950784 - * 2k3 v1.06 (Japanese) : 949248 - * 2k3 v1.05 (Japanese) : unknown - * -- threshold (2k3) -- : 927000 - * 2k3 v1.04 (Japanese) : 913408 - */ + * + * 2k v1.51 (Japanese) : 746496 + * 2k v1.50 (Japanese) : 745984 + * -- threshold (2k) -- : 735000 + * 2k v1.10 (Japanese) : 726016 + * + * 2k3 v1.09a (Japanese) : 950784 + * 2k3 v1.06 (Japanese) : 949248 + * 2k3 v1.05 (Japanese) : unknown + * -- threshold (2k3) -- : 927000 + * 2k3 v1.04 (Japanese) : 913408 + */ enum RpgrtMajorUpdateThreshold { RPG2K = 735000, RPG2K3 = 927000, @@ -408,25 +421,4 @@ std::string FileFinder::MakePath(lcf::Span components) { return path; } -static inline const char* FileFinder::GetProjectTypeLabel(ProjectType pt) { - switch (pt) { - case Supported: - return "Supported"; - case RpgMakerXp: - return "RPG Maker XP"; - case RpgMakerVx: - return "RPG Maker VX"; - case RpgMakerVxAce: - return "RPG Maker VX Ace"; - case RpgMakerMvMz: - return "RPG Maker MV/MZ"; - case WolfRpgEditor: - return "Wolf RPG Editor"; - case Encrypted2k3Maniacs: - return "Encrypted 2k3MP"; - default: - return "Unknown"; - } -} - #endif diff --git a/src/scene_gamebrowser.cpp b/src/scene_gamebrowser.cpp index 3a5fe1c1cf..913d19c8cf 100644 --- a/src/scene_gamebrowser.cpp +++ b/src/scene_gamebrowser.cpp @@ -197,18 +197,18 @@ void Scene_GameBrowser::BootGame() { return; } - if (ge.type > FileFinder::ProjectType::Supported) { - // Game is using a known unsupported engine - Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Buzzer)); - Output::Warning( - "[{}] Detected an unsupported game engine: {}", - FileFinder::GetPathAndFilename(ge.fs.GetFullPath()).second, - FileFinder::GetProjectTypeLabel(ge.type) - ); - load_window->SetVisible(false); - game_loading = false; - return; - } + if (ge.type > FileFinder::ProjectType::Supported) { + // Game is using a known unsupported engine + Main_Data::game_system->SePlay(Main_Data::game_system->GetSystemSE(Main_Data::game_system->SFX_Buzzer)); + Output::Warning( + "[{}] Detected an unsupported game engine: {}", + FileFinder::GetPathAndFilename(ge.fs.GetFullPath()).second, + FileFinder::kProjectType.tag(ge.type) + ); + load_window->SetVisible(false); + game_loading = false; + return; + } if (ge.type == FileFinder::ProjectType::Unknown && !FileFinder::OpenViewToEasyRpgFile(ge.fs)) { // Not a game: Open as directory diff --git a/src/window_gamelist.cpp b/src/window_gamelist.cpp index 7ca9e3562a..7d7cddf743 100644 --- a/src/window_gamelist.cpp +++ b/src/window_gamelist.cpp @@ -19,6 +19,7 @@ #include #include #include "window_gamelist.h" +#include "filefinder.h" #include "game_party.h" #include "bitmap.h" #include "font.h" @@ -110,7 +111,7 @@ void Window_GameList::DrawItem(int index) { contents->TextDraw(rect.x, rect.y, Font::ColorDefault, dir_name); if (ge.type > FileFinder::ProjectType::Supported) { - auto notice = fmt::format("Unsupported: {}", FileFinder::GetProjectTypeLabel(ge.type)); + auto notice = fmt::format("Unsupported: {}", FileFinder::kProjectType.tag(ge.type)); contents->TextDraw(rect.width, rect.y, Font::ColorDisabled, notice, Text::AlignRight); } }