Skip to content

Commit

Permalink
Game Browser: Only determine the project type on Windows/UNIX platforms
Browse files Browse the repository at this point in the history
Our homebrew platforms have too slow IO for this.
  • Loading branch information
Ghabry committed Jan 20, 2025
1 parent ea40afb commit 9dc544e
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass,
auto root = FileFinder::Root().Create(spath);
root.ClearCache();

std::vector<FileFinder::GameEntry> ge_list = FileFinder::FindGames(root);
auto ge_list = FileFinder::FindGames(root);

jclass jgame_class = env->FindClass("org/easyrpg/player/game_browser/Game");
jobjectArray jgame_array = env->NewObjectArray(ge_list.size(), jgame_class, nullptr);
Expand Down
4 changes: 2 additions & 2 deletions src/filefinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,8 @@ void FileFinder::DumpFilesystem(FilesystemView fs) {
}
}

std::vector<FileFinder::GameEntry> FileFinder::FindGames(FilesystemView fs, int recursion_limit, int game_limit) {
std::vector<FileFinder::GameEntry> games;
std::vector<FileFinder::FsEntry> FileFinder::FindGames(FilesystemView fs, int recursion_limit, int game_limit) {
std::vector<FileFinder::FsEntry> games;

std::function<void(FilesystemView, int)> find_recursive = [&](FilesystemView subfs, int rec_limit) -> void {
if (!subfs || rec_limit == 0 || static_cast<int>(games.size()) >= game_limit) {
Expand Down
12 changes: 10 additions & 2 deletions src/filefinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,17 @@ namespace FileFinder {
);

/**
* Helper struct combining the project's directory and its type.
* Helper struct combining the project's directory and its type (used by Game Browser)
*/
struct GameEntry {
std::string dir_name;
ProjectType type;
};

/**
* Helper struct combining project type and filesystem (used by Android Game Browser)
*/
struct FsEntry {
FilesystemView fs;
ProjectType type;
};
Expand Down Expand Up @@ -409,7 +417,7 @@ namespace FileFinder {
* @param game_limit Abort the search when this amount of games was found.
* @return Vector of game entries (filesystem view + project type) found
*/
std::vector<GameEntry> FindGames(FilesystemView fs, int recursion_limit = 3, int game_limit = 5);
std::vector<FsEntry> FindGames(FilesystemView fs, int recursion_limit = 3, int game_limit = 5);
} // namespace FileFinder

template<typename T>
Expand Down
25 changes: 15 additions & 10 deletions src/scene_gamebrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,43 +188,48 @@ void Scene_GameBrowser::BootGame() {
return;
}

auto ge = gamelist_window->GetGameEntry();
auto entry = gamelist_window->GetFilesystemEntry();

if (!ge.fs) {
if (!entry.fs) {
Output::Warning("The selected file or directory cannot be opened");
load_window->SetVisible(false);
game_loading = false;
return;
}

if (ge.type > FileFinder::ProjectType::Supported) {
if (entry.type == FileFinder::ProjectType::Unknown) {
// Fetched again for platforms where the type is not populated due to bad IO performance
entry.type = FileFinder::GetProjectType(entry.fs);
}

if (entry.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)
"{} has unsupported engine {}",
FileFinder::GetPathAndFilename(entry.fs.GetFullPath()).second,
FileFinder::kProjectType.tag(entry.type)
);
load_window->SetVisible(false);
game_loading = false;
return;
}

if (ge.type == FileFinder::ProjectType::Unknown && !FileFinder::OpenViewToEasyRpgFile(ge.fs)) {
if (entry.type == FileFinder::ProjectType::Unknown && !FileFinder::OpenViewToEasyRpgFile(entry.fs)) {
// Not a game: Open as directory
load_window->SetVisible(false);
game_loading = false;
if (!gamelist_window->Refresh(ge.fs, true)) {
if (!gamelist_window->Refresh(entry.fs, true)) {
Output::Warning("The selected file or directory cannot be opened");
return;
}
stack.push_back({ ge.fs, gamelist_window->GetIndex() });
stack.push_back({ entry.fs, gamelist_window->GetIndex() });
gamelist_window->SetIndex(0);

return;
}

FileFinder::SetGameFilesystem(ge.fs);
FileFinder::SetGameFilesystem(entry.fs);
Player::CreateGameObjects();

game_loading = false;
Expand Down
48 changes: 34 additions & 14 deletions src/window_gamelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
*/

// Headers
#include <iomanip>
#include <sstream>
#include "window_gamelist.h"
#include "filefinder.h"
#include "game_party.h"
#include "bitmap.h"
#include "font.h"
#include "system.h"

Window_GameList::Window_GameList(int ix, int iy, int iwidth, int iheight) :
Window_Selectable(ix, iy, iwidth, iheight) {
Expand Down Expand Up @@ -56,24 +54,34 @@ bool Window_GameList::Refresh(FilesystemView filesystem_base, bool show_dotdot)
}
if (dir.second.type == DirectoryTree::FileType::Regular) {
if (FileFinder::IsSupportedArchiveExtension(dir.second.name)) {
// The type is only determined on platforms with fast file IO (Windows and UNIX systems)
// A platform is considered "fast" when it does not require our custom IO buffer
#ifndef USE_CUSTOM_FILEBUF
auto fs = base_fs.Create(dir.second.name);
game_entries.push_back({ fs, FileFinder::GetProjectType(fs) });
game_entries.push_back({ dir.second.name, FileFinder::GetProjectType(fs) });
#else
game_entries.push_back({ dir.second.name, FileFinder::ProjectType::Unknown });
#endif
}
} else if (dir.second.type == DirectoryTree::FileType::Directory) {
#ifndef USE_CUSTOM_FILEBUF
auto fs = base_fs.Create(dir.second.name);
game_entries.push_back({ fs, FileFinder::GetProjectType(fs) });
game_entries.push_back({ dir.second.name, FileFinder::GetProjectType(fs) });
#else
game_entries.push_back({ dir.second.name, FileFinder::ProjectType::Unknown });
#endif
}
}

// Sort game list in place
std::sort(game_entries.begin(), game_entries.end(),
[](const FileFinder::GameEntry &ge1, const FileFinder::GameEntry &ge2) {
return strcmp(Utils::LowerCase(ge1.fs.GetSubPath()).c_str(),
Utils::LowerCase(ge2.fs.GetSubPath()).c_str()) <= 0;
return strcmp(Utils::LowerCase(ge1.dir_name).c_str(),
Utils::LowerCase(ge2.dir_name).c_str()) <= 0;
});

if (show_dotdot) {
game_entries.insert(game_entries.begin(), { base_fs.Create(".."), FileFinder::ProjectType::Unknown });
game_entries.insert(game_entries.begin(), { "..", FileFinder::ProjectType::Unknown });
}

if (HasValidEntry()) {
Expand Down Expand Up @@ -107,12 +115,23 @@ void Window_GameList::DrawItem(int index) {
contents->ClearRect(rect);

auto& ge = game_entries[index];
auto dir_name = FileFinder::GetPathAndFilename(ge.fs.GetSubPath()).second;
contents->TextDraw(rect.x, rect.y, Font::ColorDefault, dir_name);

#ifndef USE_CUSTOM_FILEBUF
auto color = Font::ColorDefault;
if (ge.type == FileFinder::Unknown) {
color = Font::ColorHeal;
} else if (ge.type > FileFinder::ProjectType::Supported) {
color = Font::ColorKnockout;
}
#else
auto color = Font::ColorDefault;
#endif

contents->TextDraw(rect.x, rect.y, color, ge.dir_name);

if (ge.type > FileFinder::ProjectType::Supported) {
auto notice = fmt::format("Unsupported: {}", FileFinder::kProjectType.tag(ge.type));
contents->TextDraw(rect.width, rect.y, Font::ColorDisabled, notice, Text::AlignRight);
auto notice = fmt::format("{}", FileFinder::kProjectType.tag(ge.type));
contents->TextDraw(rect.width, rect.y, color, notice, Text::AlignRight);
}
}

Expand Down Expand Up @@ -159,6 +178,7 @@ bool Window_GameList::HasValidEntry() {
return game_entries.size() > minval;
}

FileFinder::GameEntry Window_GameList::GetGameEntry() const {
return game_entries[GetIndex()];
FileFinder::FsEntry Window_GameList::GetFilesystemEntry() const {
const auto& entry = game_entries[GetIndex()];
return { base_fs.Create(entry.dir_name), entry.type };
}
5 changes: 2 additions & 3 deletions src/window_gamelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

// Headers
#include <vector>
#include "window_help.h"
#include "window_selectable.h"
#include "filefinder.h"

Expand Down Expand Up @@ -55,9 +54,9 @@ class Window_GameList : public Window_Selectable {
bool HasValidEntry();

/**
* @return game entry containing filesystem view and project type
* @return fs entry containing filesystem view and project type
*/
FileFinder::GameEntry GetGameEntry() const;
FileFinder::FsEntry GetFilesystemEntry() const;

private:
FilesystemView base_fs;
Expand Down

0 comments on commit 9dc544e

Please sign in to comment.