From 934e7b614c46405ff38ef38251d1a29ab9ea4e06 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 1 Aug 2022 21:41:46 +0200 Subject: [PATCH] cellPhotoExport/cellVideoExport: fix filenames --- Utilities/StrFmt.cpp | 10 +++++ Utilities/StrUtil.h | 3 ++ rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp | 50 ++++++++++++++++++++-- rpcs3/Emu/Cell/Modules/cellVideoExport.cpp | 44 +++++++++++++------ 4 files changed, 91 insertions(+), 16 deletions(-) diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 9972bc7e8c..277a3470cd 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -615,3 +615,13 @@ bool fmt::match(const std::string& source, const std::string& mask) return true; } + +std::string get_file_extension(const std::string& file_path) +{ + if (usz dotpos = file_path.find_last_of('.'); dotpos != std::string::npos && dotpos + 1 < file_path.size()) + { + return file_path.substr(dotpos + 1); + } + + return {}; +} diff --git a/Utilities/StrUtil.h b/Utilities/StrUtil.h index 2d0fcfe742..c2815fd0d0 100644 --- a/Utilities/StrUtil.h +++ b/Utilities/StrUtil.h @@ -27,6 +27,9 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max); // Convert string to unsigned integer bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max); +// Get the file extension of a file path ("png", "jpg", etc.) +std::string get_file_extension(const std::string& file_path); + namespace fmt { std::string replace_all(std::string_view src, std::string_view from, std::string_view to, usz count = -1); diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp index 4072fc8a7f..42dce118d7 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp @@ -2,6 +2,7 @@ #include "Emu/Cell/PPUModule.h" #include "Emu/IdManager.h" #include "Emu/VFS.h" +#include "Utilities/StrUtil.h" #include "cellSysutil.h" LOG_CHANNEL(cellPhotoExport); @@ -115,7 +116,7 @@ std::string get_available_photo_path(const std::string& filename) // Do not overwrite existing files. Add a suffix instead. for (u32 i = 0; fs::exists(dst_path); i++) { - const std::string suffix = std::to_string(i); + const std::string suffix = fmt::format("_%d", i); std::string new_filename = filename; if (const usz pos = new_filename.find_last_of('.'); pos != std::string::npos) @@ -196,12 +197,23 @@ error_code cellPhotoRegistFromFile(vm::cptr path, vm::cptr photo_tit return { CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM, file_path }; } + std::string filename = photo_title.get_ptr(); + + if (filename.empty()) + { + return { CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM, "title empty" }; + } + + if (const std::string extension = get_file_extension(file_path); !extension.empty()) + { + fmt::append(filename, ".%s", extension); + } + sysutil_register_cb([=](ppu_thread& ppu) -> s32 { auto& pexp = g_fxo->get(); pexp.progress = 0; // 0% - const std::string filename = file_path.substr(file_path.find_last_of('/') + 1); const std::string src_path = vfs::get(file_path); const std::string dst_path = get_available_photo_path(filename); @@ -312,6 +324,10 @@ error_code cellPhotoExportFromFile(vm::cptr srcHddDir, vm::cptr srcH return CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM; } + // TODO: check param members ? + + cellPhotoExport.notice("cellPhotoExportFromFile: param: photo_title=%s, game_title=%s, game_comment=%s", param->photo_title, param->game_title, param->game_comment); + const std::string file_path = fmt::format("%s/%s", srcHddDir.get_ptr(), srcHddFile.get_ptr()); if (!check_photo_path(file_path)) @@ -319,12 +335,23 @@ error_code cellPhotoExportFromFile(vm::cptr srcHddDir, vm::cptr srcH return { CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM, file_path }; } + std::string filename = param->photo_title.get_ptr(); + + if (filename.empty()) + { + return { CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM, "title empty" }; + } + + if (const std::string extension = get_file_extension(file_path); !extension.empty()) + { + fmt::append(filename, ".%s", extension); + } + sysutil_register_cb([=](ppu_thread& ppu) -> s32 { auto& pexp = g_fxo->get(); pexp.progress = 0; // 0% - const std::string filename = file_path.substr(file_path.find_last_of('/') + 1); const std::string src_path = vfs::get(file_path); const std::string dst_path = get_available_photo_path(filename); @@ -371,6 +398,10 @@ error_code cellPhotoExportFromFileWithCopy(vm::cptr srcHddDir, vm::cptrphoto_title, param->game_title, param->game_comment); + const std::string file_path = fmt::format("%s/%s", srcHddDir.get_ptr(), srcHddFile.get_ptr()); if (!check_photo_path(file_path)) @@ -378,12 +409,23 @@ error_code cellPhotoExportFromFileWithCopy(vm::cptr srcHddDir, vm::cptrphoto_title.get_ptr(); + + if (filename.empty()) + { + return { CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM, "title empty" }; + } + + if (const std::string extension = get_file_extension(file_path); !extension.empty()) + { + fmt::append(filename, ".%s", extension); + } + sysutil_register_cb([=](ppu_thread& ppu) -> s32 { auto& pexp = g_fxo->get(); pexp.progress = 0; // 0% - const std::string filename = file_path.substr(file_path.find_last_of('/') + 1); const std::string src_path = vfs::get(file_path); const std::string dst_path = get_available_photo_path(filename); diff --git a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp index 9d8cd5e2e0..8119726abe 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp @@ -2,7 +2,7 @@ #include "Emu/Cell/PPUModule.h" #include "Emu/IdManager.h" #include "Emu/VFS.h" - +#include "Utilities/StrUtil.h" #include "cellSysutil.h" LOG_CHANNEL(cellVideoExport); @@ -119,7 +119,7 @@ std::string get_available_movie_path(const std::string& filename) // Do not overwrite existing files. Add a suffix instead. for (u32 i = 0; fs::exists(dst_path); i++) { - const std::string suffix = std::to_string(i); + const std::string suffix = fmt::format("_%d", i); std::string new_filename = filename; if (const usz pos = new_filename.find_last_of('.'); pos != std::string::npos) @@ -219,11 +219,15 @@ error_code cellVideoExportFromFileWithCopy(vm::cptr srcHddDir, vm::cptrtitle, param->game_title, param->game_comment, param->editable); + const std::string file_path = fmt::format("%s/%s", srcHddDir, srcHddFile); if (!check_movie_path(file_path)) @@ -231,9 +235,16 @@ error_code cellVideoExportFromFileWithCopy(vm::cptr srcHddDir, vm::cptrtitle.get_ptr(); + + if (filename.empty()) { - return CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM; + return { CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM, "title empty" }; + } + + if (const std::string extension = get_file_extension(file_path); !extension.empty()) + { + fmt::append(filename, ".%s", extension); } sysutil_register_cb([=](ppu_thread& ppu) -> s32 @@ -241,7 +252,6 @@ error_code cellVideoExportFromFileWithCopy(vm::cptr srcHddDir, vm::cptrget(); vexp.progress = 0; // 0% - const std::string filename = file_path.substr(file_path.find_last_of('/') + 1); const std::string src_path = vfs::get(file_path); const std::string dst_path = get_available_movie_path(filename); @@ -273,11 +283,15 @@ error_code cellVideoExportFromFile(vm::cptr srcHddDir, vm::cptr srcH { cellVideoExport.todo("cellVideoExportFromFile(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata); - if (!param || !srcHddDir || !srcHddDir[0] || !srcHddFile || !srcHddFile[0]) + if (!param || !funcFinish || !srcHddDir || !srcHddDir[0] || !srcHddFile || !srcHddFile[0]) { return CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM; } - + + // TODO: check param members ? + + cellVideoExport.notice("cellVideoExportFromFile: param: title=%s, game_title=%s, game_comment=%s, editable=%d", param->title, param->game_title, param->game_comment, param->editable); + const std::string file_path = fmt::format("%s/%s", srcHddDir, srcHddFile); if (!check_movie_path(file_path)) @@ -285,9 +299,16 @@ error_code cellVideoExportFromFile(vm::cptr srcHddDir, vm::cptr srcH return { CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM, file_path }; } - if (!funcFinish) + std::string filename = param->title.get_ptr(); + + if (filename.empty()) { - return CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM; + return { CELL_VIDEO_EXPORT_UTIL_ERROR_PARAM, "title empty" }; + } + + if (const std::string extension = get_file_extension(file_path); !extension.empty()) + { + fmt::append(filename, ".%s", extension); } sysutil_register_cb([=](ppu_thread& ppu) -> s32 @@ -295,7 +316,6 @@ error_code cellVideoExportFromFile(vm::cptr srcHddDir, vm::cptr srcH auto& vexp = g_fxo->get(); vexp.progress = 0; // 0% - const std::string filename = file_path.substr(file_path.find_last_of('/') + 1); const std::string src_path = vfs::get(file_path); const std::string dst_path = get_available_movie_path(filename);