Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QoL: detect unsupported engines #3326

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d01908f
Add detecting project type of the game
Primekick Jan 6, 2025
8c636c8
Change FileFinder::FindGames to find and return game entries (includi…
Primekick Jan 6, 2025
e21e7c1
Add creating a Game instance from unsupported project type
Primekick Jan 7, 2025
9197e55
Change Game card to include additional information for unsupported pr…
Primekick Jan 7, 2025
f0777b0
Fix crash on loading games from cache
Primekick Jan 7, 2025
92a76cb
Show unsupported games last on the list
Primekick Jan 7, 2025
08a4eef
Add explanation dialog when trying to launch unsupported game
Primekick Jan 7, 2025
caaff24
Notify user when trying to launch a game running on a known unsupport…
Primekick Jan 7, 2025
8886081
Show information for unsupported engines directly on the game list
Primekick Jan 7, 2025
dfc5295
Add wildcard file search
Primekick Jan 7, 2025
2d78864
Split up and change the unsupported engine explanation
Primekick Jan 7, 2025
3556522
Rename fs_list to ge_list for clarity
Primekick Jan 7, 2025
945e522
Add more newlines between unsupported project explanation parts, fix …
Primekick Jan 7, 2025
cc4975a
Add encrypted 2k3MP to unsupported engines
Primekick Jan 14, 2025
305a1ea
Android: Fix "Show folder name" setting for unsupported games
Ghabry Jan 20, 2025
ea40afb
FileFilder: Make wildcard processing an option
Ghabry Jan 20, 2025
9dc544e
Game Browser: Only determine the project type on Windows/UNIX platforms
Ghabry Jan 20, 2025
2c19a17
(Sim)RM95: Use detection suggested by @florianessl
Ghabry Jan 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 3 additions & 3 deletions src/directory_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
23 changes: 14 additions & 9 deletions src/directory_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::string, Entry>>;
Expand Down Expand Up @@ -148,24 +152,25 @@ class DirectoryTree {
static bool WildcardMatch(const StringView& pattern, const StringView& text);

template<class T>
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;
});
if (it != cache.end() && it->first == what) {
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();
}

Expand Down
20 changes: 17 additions & 3 deletions src/filefinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -341,6 +347,14 @@ FileFinder::ProjectType FileFinder::GetProjectType(const FilesystemView &fs) {
return FileFinder::ProjectType::Encrypted2k3Maniacs;
}

if (!fs.FindFile("Game.RPG").empty()) {
Ghabry marked this conversation as resolved.
Show resolved Hide resolved
return FileFinder::ProjectType::RpgMaker95;
}

if (!fs.FindFile("Game.DAT").empty()) {
return FileFinder::ProjectType::SimRpgMaker95;
}

return FileFinder::ProjectType::Unknown;
}

Expand Down
64 changes: 28 additions & 36 deletions src/filefinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "string_view.h"
#include "directory_tree.h"

#include <lcf/enum_tags.h>
#include <string>
#include <cstdio>
#include <ios>
Expand Down Expand Up @@ -60,8 +61,23 @@ namespace FileFinder {
RpgMakerMvMz,
WolfRpgEditor,
Encrypted2k3Maniacs,
RpgMaker95,
SimRpgMaker95
};

constexpr auto kProjectType = lcf::makeEnumTags<ProjectType>(
"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.
*/
Expand All @@ -70,9 +86,6 @@ namespace FileFinder {
ProjectType type;
};

/** @return Human readable project type label */
static const char* GetProjectTypeLabel(ProjectType pt);

/**
* Quits FileFinder.
*/
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -408,25 +421,4 @@ std::string FileFinder::MakePath(lcf::Span<T> 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
24 changes: 12 additions & 12 deletions src/scene_gamebrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/window_gamelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <iomanip>
#include <sstream>
#include "window_gamelist.h"
#include "filefinder.h"
#include "game_party.h"
#include "bitmap.h"
#include "font.h"
Expand Down Expand Up @@ -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);
}
}
Expand Down