1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 20:22:30 +01:00

cellSaveData/cellMsgDialog: implement cellSaveDataDelete

This commit is contained in:
Megamouse 2019-07-13 21:48:54 +02:00
parent 0b720aeb59
commit 896cfd2ade
5 changed files with 150 additions and 9 deletions

View File

@ -32,6 +32,9 @@ MsgDialogBase::~MsgDialogBase()
{
}
// variable used to immediately get the response from auxiliary message dialogs (callbacks would be async)
atomic_t<s32> g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
// forward declaration for open_msg_dialog
error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam);
@ -129,7 +132,6 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
break;
}
case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO:
{
if (_type.default_cursor > 1 || _type.progress_bar_count)
@ -139,7 +141,6 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
break;
}
case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK:
{
if (_type.default_cursor || _type.progress_bar_count)
@ -149,7 +150,6 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
break;
}
default: return CELL_MSGDIALOG_ERROR_PARAM;
}
@ -174,6 +174,8 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
return CELL_SYSUTIL_ERROR_BUSY;
}
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
const auto res = manager->create<rsx::overlays::message_dialog>()->show(msgString.get_ptr(), _type, [callback, userData](s32 status)
{
if (callback)
@ -227,6 +229,7 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
// Run asynchronously in GUI thread
Emu.CallAfter([&]()
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
dlg->Create(msgString.get_ptr());
lv2_obj::awake(&ppu);
});

View File

@ -83,6 +83,8 @@ enum class MsgDialogState
Close,
};
extern atomic_t<s32> g_last_user_response;
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback = vm::null, vm::ptr<void> userData = vm::null, vm::ptr<void> extParam = vm::null);
error_code open_exit_dialog(const std::string& message, bool is_exit_requested);

View File

@ -6,6 +6,7 @@
#include "Emu/Cell/Modules/cellSysutil.h"
#include "cellSaveData.h"
#include "cellMsgDialog.h"
#include "Loader/PSF.h"
#include "Utilities/StrUtil.h"
@ -89,6 +90,134 @@ vm::gvar<savedata_context> g_savedata_context;
std::mutex g_savedata_mutex;
static std::vector<SaveDataEntry> get_save_entries(const std::string& base_dir, const std::string& prefix)
{
std::vector<SaveDataEntry> save_entries;
if (base_dir.empty() || prefix.empty())
{
return save_entries;
}
// get the saves matching the supplied prefix
for (auto&& entry : fs::dir(base_dir))
{
if (!entry.is_directory || entry.name == "." || entry.name == "..")
{
continue;
}
entry.name = vfs::unescape(entry.name);
if (entry.name.substr(0, prefix.size()) != prefix)
{
continue;
}
// PSF parameters
const psf::registry psf = psf::load_object(fs::file(base_dir + entry.name + "/PARAM.SFO"));
if (psf.empty())
{
continue;
}
SaveDataEntry save_entry;
save_entry.dirName = psf.at("SAVEDATA_DIRECTORY").as_string();
save_entry.listParam = psf.at("SAVEDATA_LIST_PARAM").as_string();
save_entry.title = psf.at("TITLE").as_string();
save_entry.subtitle = psf.at("SUB_TITLE").as_string();
save_entry.details = psf.at("DETAIL").as_string();
for (const auto entry2 : fs::dir(base_dir + entry.name))
{
save_entry.size += entry2.size;
}
save_entry.atime = entry.atime;
save_entry.mtime = entry.mtime;
save_entry.ctime = entry.ctime;
if (fs::file icon{base_dir + entry.name + "/ICON0.PNG"})
save_entry.iconBuf = icon.to_vector<uchar>();
save_entry.isNew = false;
save_entries.emplace_back(save_entry);
}
return save_entries;
}
static error_code select_and_delete(ppu_thread& ppu)
{
std::unique_lock lock(g_savedata_mutex, std::try_to_lock);
if (!lock)
{
return CELL_SAVEDATA_ERROR_BUSY;
}
const std::string base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", Emu.GetUsrId()));
auto save_entries = get_save_entries(base_dir, Emu.GetTitleID());
s32 selected = -1;
s32 focused = -1;
while (true)
{
// Yield
lv2_obj::sleep(ppu);
// Display Save Data List asynchronously in the GUI thread.
selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, SAVEDATA_OP_LIST_DELETE, vm::null);
// Reschedule
if (ppu.check_state())
{
return 0;
}
// Abort if dialog was canceled
if (selected == -2)
{
return CELL_CANCEL;
}
// Set focused entry for the next iteration
focused = save_entries.empty() ? -1 : selected;
// Get information from the selected entry
SaveDataEntry entry = save_entries[selected];
const std::string info = entry.title + "\n" + entry.subtitle + "\n" + entry.details;
// Get user confirmation
std::string msg = "Do you really want to delete this entry?\n\n" + info;
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(msg));
if (res != CELL_OK)
{
return CELL_SAVEDATA_ERROR_INTERNAL;
}
if (g_last_user_response.load() == CELL_MSGDIALOG_BUTTON_YES)
{
// Remove directory
const std::string path = base_dir + save_entries[selected].dirName;
fs::remove_all(path);
// Remove entry from the list and reset the selection
save_entries.erase(save_entries.cbegin() + selected);
selected = -1;
// Display success message (return value should be irrelevant here)
msg = "Successfully removed entry!\n\n" + info;
cellSaveData.success("%s", msg);
res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, vm::make_str(msg));
}
}
return CELL_CANCEL;
}
static bool savedata_check_args(u32 operation, u32 version, vm::cptr<char> dirName,
u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncFixed funcFixed, PFuncStat funcStat,
PFuncFile funcFile, u32 container, u32 unk_op_flags, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
@ -1333,18 +1462,18 @@ error_code cellSaveDataListAutoLoad(ppu_thread& ppu, u32 version, u32 errDialog,
return savedata_op(ppu, SAVEDATA_OP_LIST_AUTO_LOAD, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null);
}
error_code cellSaveDataDelete2(u32 container)
error_code cellSaveDataDelete(ppu_thread& ppu, u32 container)
{
cellSaveData.todo("cellSaveDataDelete2(container=0x%x)", container);
cellSaveData.warning("cellSaveDataDelete(container=0x%x)", container);
return CELL_CANCEL;
return select_and_delete(ppu);
}
error_code cellSaveDataDelete(u32 container)
error_code cellSaveDataDelete2(ppu_thread& ppu, u32 container)
{
cellSaveData.todo("cellSaveDataDelete(container=0x%x)", container);
cellSaveData.warning("cellSaveDataDelete2(container=0x%x)", container);
return CELL_CANCEL;
return select_and_delete(ppu);
}
error_code cellSaveDataFixedDelete(ppu_thread& ppu, PSetList setList, PSetBuf setBuf, PFuncFixed funcFixed, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)

View File

@ -323,7 +323,10 @@ namespace rsx
pad::SetIntercepted(false);
if (on_close && use_callback)
{
g_last_user_response = return_code;
on_close(return_code);
}
}
void overlay::refresh()

View File

@ -93,12 +93,14 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title)
connect(m_button_yes, &QAbstractButton::clicked, [=]
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_YES;
on_close(CELL_MSGDIALOG_BUTTON_YES);
m_dialog->accept();
});
connect(m_button_no, &QAbstractButton::clicked, [=]
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_NO;
on_close(CELL_MSGDIALOG_BUTTON_NO);
m_dialog->accept();
});
@ -123,6 +125,7 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title)
connect(m_button_ok, &QAbstractButton::clicked, [=]
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_OK;
on_close(CELL_MSGDIALOG_BUTTON_OK);
m_dialog->accept();
});
@ -134,6 +137,7 @@ void msg_dialog_frame::Create(const std::string& msg, const std::string& title)
{
if (!type.disable_cancel)
{
g_last_user_response = CELL_MSGDIALOG_BUTTON_ESCAPE;
on_close(CELL_MSGDIALOG_BUTTON_ESCAPE);
}
});