mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-10-30 19:23:39 +01:00
Big picture: recursive folder scanning (#5223)
* add recursive scanning - force depth 2 for now, make configurable later * make setting configurable * match item widths * correctly load language as specific, fix profile button naming with multiple same titleid entries * catch fs errors, while ensuring all other items are scanned
This commit is contained in:
1 parent
ead912cf95
commit
8cd2ea8c41
4 files changed
+139
-57
No files matched your search
@@ -199,6 +199,7 @@ struct GeneralSettings {
|
||||
Setting<bool> show_fps_counter{false};
|
||||
Setting<int> console_language{1};
|
||||
Setting<int> big_picture_scale{1000};
|
||||
Setting<int> big_picture_folder_depth{2};
|
||||
Setting<std::string> shadnet_server{"srv.shadps4.net:31313"};
|
||||
Setting<std::string> shadnet_webapi_server{"http://srv.shadps4.net:31315"};
|
||||
Setting<std::string> signaling_info{};
|
||||
@@ -241,8 +242,9 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GeneralSettings, install_dirs, addon_install_
|
||||
trophy_popup_disabled, trophy_notification_duration, show_splash,
|
||||
trophy_notification_side, connected_to_network,
|
||||
discord_rpc_enabled, show_fps_counter, console_language,
|
||||
big_picture_scale, shadnet_server, shadnet_webapi_server,
|
||||
signaling_info, enable_upnp, redzone_patches)
|
||||
big_picture_scale, big_picture_folder_depth, shadnet_server,
|
||||
shadnet_webapi_server, signaling_info, enable_upnp,
|
||||
redzone_patches)
|
||||
|
||||
// -------------------------------
|
||||
// Log settings
|
||||
@@ -659,6 +661,7 @@ public:
|
||||
SETTING_FORWARD_BOOL(m_general, ShowFpsCounter, show_fps_counter)
|
||||
SETTING_FORWARD(m_general, ConsoleLanguage, console_language)
|
||||
SETTING_FORWARD(m_general, BigPictureScale, big_picture_scale)
|
||||
SETTING_FORWARD(m_general, BigPictureFolderDepth, big_picture_folder_depth)
|
||||
SETTING_FORWARD(m_general, ShadNetServer, shadnet_server)
|
||||
SETTING_FORWARD(m_general, ShadNetWebApiServer, shadnet_webapi_server)
|
||||
SETTING_FORWARD(m_general, SignalingInfo, signaling_info)
|
||||
|
||||
@@ -162,62 +162,108 @@ SDL_Texture* LoadSdlTextureDataFromFile(std::filesystem::path filePath) {
|
||||
return LoadSdlTextureData(data);
|
||||
}
|
||||
|
||||
void scanFolder(std::vector<IconInfo>& icons, std::filesystem::path folderPath, int depth) {
|
||||
if (depth > EmulatorSettings.GetBigPictureFolderDepth()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::directory_iterator it(folderPath, std::filesystem::directory_options::none,
|
||||
ec);
|
||||
std::filesystem::directory_iterator end;
|
||||
|
||||
if (ec) {
|
||||
LOG_ERROR(ImGui, "Cannot open folder: {} due to filesystem error: {}", folderPath.string(),
|
||||
ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
while (it != end) {
|
||||
// For access errors getting it.path may not be safe, so log parent folder
|
||||
if (ec) {
|
||||
LOG_ERROR(ImGui, "Cannot access item inside folder {} due to error: {}",
|
||||
folderPath.string(), ec.message());
|
||||
ec.clear();
|
||||
it.increment(ec);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& entry = *it;
|
||||
bool isEntryDir = std::filesystem::is_directory(entry, ec);
|
||||
|
||||
if (ec) {
|
||||
LOG_ERROR(ImGui, "Skipping file/subfolder {} due to filesystem error: {}",
|
||||
entry.path().string(), ec.message());
|
||||
ec.clear();
|
||||
it.increment(ec);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isEntryDir && !std::filesystem::exists(entry.path() / "eboot.bin", ec)) {
|
||||
scanFolder(icons, entry.path(), depth + 1);
|
||||
}
|
||||
|
||||
std::string pathstring = entry.path().filename().string();
|
||||
if (pathstring.ends_with("-UPDATE") || pathstring.ends_with("-patch") ||
|
||||
(!isEntryDir && !Core::FileSys::IsZArchiveFile(entry))) {
|
||||
it.increment(ec);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Core::FileSys::IsZArchiveFile(entry)) {
|
||||
size_t start = pathstring.length() - 3;
|
||||
for (size_t i = start; i < pathstring.length(); ++i) {
|
||||
pathstring[i] =
|
||||
static_cast<char>(std::tolower(static_cast<unsigned char>(pathstring[i])));
|
||||
}
|
||||
|
||||
if (pathstring.ends_with("-UPDATE.zar") || pathstring.ends_with("-patch.zar")) {
|
||||
it.increment(ec);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
IconInfo icon;
|
||||
PSF psf;
|
||||
const std::string sfoFileName = "param.sfo";
|
||||
std::filesystem::path sfoPath = UpdateChecker(sfoFileName, entry.path());
|
||||
|
||||
if (std::filesystem::exists(sfoPath, ec) && psf.Open(sfoPath)) {
|
||||
if (const auto title = psf.GetString("TITLE"); title.has_value()) {
|
||||
icon.title = *title;
|
||||
}
|
||||
|
||||
if (const auto title_id = psf.GetString("TITLE_ID"); title_id.has_value()) {
|
||||
icon.serial = *title_id;
|
||||
}
|
||||
} else {
|
||||
it.increment(ec);
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string iconFileName = "icon0.png";
|
||||
std::filesystem::path iconPath = UpdateChecker(iconFileName, entry.path());
|
||||
|
||||
SDL_Texture* texture = LoadSdlTextureDataFromFile(iconPath);
|
||||
icon.textureId = ImTextureID(texture);
|
||||
|
||||
icon.ebootPath = entry.path() / "eboot.bin";
|
||||
if (Core::FileSys::IsZArchiveFile(entry.path())) {
|
||||
icon.ebootPath = entry.path();
|
||||
}
|
||||
|
||||
icon.focusState = false;
|
||||
icons.push_back(icon);
|
||||
it.increment(ec);
|
||||
}
|
||||
}
|
||||
|
||||
void GetGameIconInfo(std::vector<IconInfo>& icons) {
|
||||
icons.clear();
|
||||
|
||||
for (const auto& installLoc : EmulatorSettings.GetAllGameInstallDirs()) {
|
||||
if (installLoc.enabled && std::filesystem::exists(installLoc.path)) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(installLoc.path)) {
|
||||
|
||||
std::string pathstring = entry.path().filename().string();
|
||||
if (pathstring.ends_with("-UPDATE") || pathstring.ends_with("-patch") ||
|
||||
(!entry.is_directory() && !Core::FileSys::IsZArchiveFile(entry))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Core::FileSys::IsZArchiveFile(entry)) {
|
||||
size_t start = pathstring.length() - 3;
|
||||
for (size_t i = start; i < pathstring.length(); ++i) {
|
||||
pathstring[i] = static_cast<char>(
|
||||
std::tolower(static_cast<unsigned char>(pathstring[i])));
|
||||
}
|
||||
|
||||
if (pathstring.ends_with("-UPDATE.zar") || pathstring.ends_with("-patch.zar")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
IconInfo icon;
|
||||
PSF psf;
|
||||
const std::string sfoFileName = "param.sfo";
|
||||
std::filesystem::path sfoPath = UpdateChecker(sfoFileName, entry.path());
|
||||
|
||||
if (std::filesystem::exists(sfoPath) && psf.Open(sfoPath)) {
|
||||
if (const auto title = psf.GetString("TITLE"); title.has_value()) {
|
||||
icon.title = *title;
|
||||
}
|
||||
|
||||
if (const auto title_id = psf.GetString("TITLE_ID"); title_id.has_value()) {
|
||||
icon.serial = *title_id;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string iconFileName = "icon0.png";
|
||||
std::filesystem::path iconPath = UpdateChecker(iconFileName, entry.path());
|
||||
|
||||
SDL_Texture* texture = LoadSdlTextureDataFromFile(iconPath);
|
||||
icon.textureId = ImTextureID(texture);
|
||||
|
||||
icon.ebootPath = entry.path() / "eboot.bin";
|
||||
if (Core::FileSys::IsZArchiveFile(entry.path())) {
|
||||
icon.ebootPath = entry.path();
|
||||
}
|
||||
|
||||
icon.focusState = false;
|
||||
icons.push_back(icon);
|
||||
}
|
||||
scanFolder(icons, installLoc.path, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,14 @@ int SettingsWindow::GetComboIndex(std::string selection, std::vector<std::string
|
||||
}
|
||||
|
||||
void SettingsWindow::LoadSettings(std::string profile) {
|
||||
// Global-only settings
|
||||
EmulatorSettings.Load();
|
||||
scanDepthSetting = EmulatorSettings.GetBigPictureFolderDepth();
|
||||
|
||||
const bool isSpecific = currentProfile != "Global";
|
||||
isSpecific ? EmulatorSettings.Load(profile) : EmulatorSettings.Load();
|
||||
if (isSpecific) {
|
||||
EmulatorSettings.Load(profile);
|
||||
}
|
||||
|
||||
/////////// General Tab
|
||||
int languageIndex = EmulatorSettings.GetConsoleLanguage();
|
||||
@@ -43,7 +49,6 @@ void SettingsWindow::LoadSettings(std::string profile) {
|
||||
language = key;
|
||||
}
|
||||
}
|
||||
|
||||
consoleLanguageSetting = GetComboIndex(language, languageOptions);
|
||||
volumeSetting = EmulatorSettings.GetVolumeSlider();
|
||||
showSplashSetting = EmulatorSettings.IsShowSplash();
|
||||
@@ -513,8 +518,10 @@ void SettingsWindow::DrawProfileSelector() {
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string profileLabel =
|
||||
i == 0 ? "Global" : profileIcons[i].serial + " - " + profileIcons[i].title;
|
||||
std::string profileLabel = i == 0
|
||||
? "Global"
|
||||
: profileIcons[i].serial + " - " +
|
||||
profileIcons[i].title + "##" + std::to_string(i);
|
||||
if (ImGui::Button(profileLabel.c_str(),
|
||||
ImVec2(ImGui::GetContentRegionAvail().x, 0.0f))) {
|
||||
|
||||
@@ -595,6 +602,29 @@ void SettingsWindow::DrawGameFolderManager() {
|
||||
ImGui::SetNextWindowSize(viewport->Size);
|
||||
}
|
||||
|
||||
float buttonWidth = ImGui::GetItemRectSize().x;
|
||||
ImGui::PushItemWidth(buttonWidth);
|
||||
if (ImGui::SliderInt("Folder Scan Depth", &scanDepthSetting, 0, 5)) {
|
||||
std::string profile;
|
||||
const bool isGlobal = currentProfile == "Global";
|
||||
if (!isGlobal) {
|
||||
profile = currentProfile.substr(0, 9);
|
||||
EmulatorSettings.Load();
|
||||
}
|
||||
|
||||
EmulatorSettings.SetBigPictureFolderDepth(scanDepthSetting);
|
||||
EmulatorSettings.Save();
|
||||
|
||||
if (!isGlobal) {
|
||||
EmulatorSettings.Load(profile);
|
||||
}
|
||||
|
||||
if (!isGameRunning) {
|
||||
GetProfileInfo();
|
||||
}
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (ImGuiFileDialog::Instance()->Display("OpenFolder", child_flags | ImGuiWindowFlags_NoMove)) {
|
||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
||||
GameInstallDir dir;
|
||||
|
||||
@@ -166,6 +166,9 @@ private:
|
||||
bool pipelineCacheArchiveSetting;
|
||||
int extraDmemSetting;
|
||||
int vblankFrequencySetting;
|
||||
|
||||
// Folders tab
|
||||
int scanDepthSetting;
|
||||
};
|
||||
|
||||
} // namespace ImGuiEmuSettings
|
||||
Reference in new issue
Block a user