cellSaveData fixes

This commit is contained in:
Nekotekina 2017-11-14 17:49:28 +03:00
parent 358afc045d
commit 16d7023a92
6 changed files with 35 additions and 33 deletions

View File

@ -37,7 +37,7 @@ enum : u32
SAVEDATA_OP_FIXED_SAVE = 6, SAVEDATA_OP_FIXED_SAVE = 6,
SAVEDATA_OP_FIXED_LOAD = 7, SAVEDATA_OP_FIXED_LOAD = 7,
SAVEDATA_OP_FIXED_DELETE = 14, SAVEDATA_OP_FIXED_DELETE = 14,
}; };
namespace namespace
@ -85,7 +85,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
//TODO: get current user ID //TODO: get current user ID
// userId(0) = CELL_SYSUTIL_USERID_CURRENT // userId(0) = CELL_SYSUTIL_USERID_CURRENT
// path of the specified user (00000001 by default) // path of the specified user (00000001 by default)
const std::string& base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u)); const std::string base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
result->userdata = userdata; // probably should be assigned only once (allows the callback to change it) result->userdata = userdata; // probably should be assigned only once (allows the callback to change it)
@ -98,9 +98,9 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
listGet->dirNum = 0; listGet->dirNum = 0;
listGet->dirListNum = 0; listGet->dirListNum = 0;
listGet->dirList.set(setBuf->buf.addr()); listGet->dirList.set(setBuf->buf.addr());
memset(listGet->reserved, 0, sizeof(listGet->reserved)); std::memset(listGet->reserved, 0, sizeof(listGet->reserved));
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" }); const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), {"|"});
// get the saves matching the supplied prefix // get the saves matching the supplied prefix
for (auto&& entry : fs::dir(base_dir)) for (auto&& entry : fs::dir(base_dir))
@ -204,7 +204,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
auto& dir = *dir_list++; auto& dir = *dir_list++;
strcpy_trunc(dir.dirName, entry.dirName); strcpy_trunc(dir.dirName, entry.dirName);
strcpy_trunc(dir.listParam, entry.listParam); strcpy_trunc(dir.listParam, entry.listParam);
memset(dir.reserved, 0, sizeof(dir.reserved)); std::memset(dir.reserved, 0, sizeof(dir.reserved));
} }
s32 selected = -1; s32 selected = -1;
@ -217,14 +217,14 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0) if (result->result < 0)
{ {
//TODO: display dialog //TODO: display dialog
cellSaveData.warning("savedata_op(): funcList returned < 0."); cellSaveData.warning("savedata_op(): funcList returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT; return CELL_SAVEDATA_ERROR_CBRESULT;
} }
// if the callback has returned ok, lets return OK. // if the callback has returned ok, lets return OK.
// typically used at game launch when no list is actually required. // typically used at game launch when no list is actually required.
// CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone // CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
{ {
return CELL_OK; return CELL_OK;
} }
@ -243,16 +243,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
return true; return true;
}), save_entries.end()); }), save_entries.end());
// Add any new data (not currently supported by the UI)
//if (listSet->newData)
//{
// SaveDataEntry *_saveDataEntry = new SaveDataEntry();
// _saveDataEntry->dirName = listSet->newData->dirName.get_ptr();
// save_entry.dirName = listSet->newData->dirName.get_ptr();
// save_entries.emplace_back(*_saveDataEntry);
//}
// Focus save data // Focus save data
s32 focused = -1; s32 focused = -1;
@ -324,13 +314,12 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
} }
} }
// Display Save Data List but do so asynchronously in the GUI thread. // Display Save Data List asynchronously in the GUI thread.
bool hasNewData = (bool)listSet->newData; // newData
atomic_t<bool> dlg_result(false); atomic_t<bool> dlg_result(false);
Emu.CallAfter([&]() Emu.CallAfter([&]()
{ {
selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, hasNewData, listSet); selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, operation, listSet);
dlg_result = true; dlg_result = true;
}); });
@ -359,7 +348,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
funcFixed(ppu, result, listGet, fixedSet); funcFixed(ppu, result, listGet, fixedSet);
// skip all following steps if OK_LAST // skip all following steps if OK_LAST
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
{ {
return CELL_OK; return CELL_OK;
} }
@ -371,7 +360,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
// 0 = none // 0 = none
// 1 = skip confirmation dialog // 1 = skip confirmation dialog
cellSaveData.warning("savedata_op(): funcFixed returned < 0."); cellSaveData.warning("savedata_op(): funcFixed returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT; return CELL_SAVEDATA_ERROR_CBRESULT;
} }
@ -504,11 +493,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0) if (result->result < 0)
{ {
cellSaveData.warning("savedata_op(): funcStat returned 0x%x", result->result); cellSaveData.warning("savedata_op(): funcStat returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT; return CELL_SAVEDATA_ERROR_CBRESULT;
} }
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
{ {
return CELL_OK; return CELL_OK;
} }
@ -607,7 +596,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
if (result->result < 0) if (result->result < 0)
{ {
cellSaveData.warning("savedata_op(): funcFile returned < 0."); cellSaveData.warning("savedata_op(): funcFile returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT; return CELL_SAVEDATA_ERROR_CBRESULT;
} }

View File

@ -291,5 +291,5 @@ class SaveDialogBase
public: public:
virtual ~SaveDialogBase(); virtual ~SaveDialogBase();
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) = 0; virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet) = 0;
}; };

View File

@ -1,9 +1,9 @@
#include "save_data_dialog.h" #include "save_data_dialog.h"
#include "save_data_list_dialog.h" #include "save_data_list_dialog.h"
s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet)
{ {
save_data_list_dialog sdid(save_entries, focused, isSaving); save_data_list_dialog sdid(save_entries, focused, op, listSet);
sdid.exec(); sdid.exec();
return sdid.GetSelection(); return sdid.GetSelection();
} }

View File

@ -7,5 +7,5 @@
class save_data_dialog : public SaveDialogBase class save_data_dialog : public SaveDialogBase
{ {
public: public:
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) override; virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet) override;
}; };

View File

@ -14,11 +14,24 @@ constexpr auto qstr = QString::fromStdString;
//Show up the savedata list, either to choose one to save/load or to manage saves. //Show up the savedata list, either to choose one to save/load or to manage saves.
//I suggest to use function callbacks to give save data list or get save data entry. (Not implemented or stubbed) //I suggest to use function callbacks to give save data list or get save data entry. (Not implemented or stubbed)
save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, bool is_saving, QWidget* parent) save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, u32 op, vm::ptr<CellSaveDataListSet> listSet, QWidget* parent)
: QDialog(parent), m_save_entries(entries), m_entry(-1), m_entry_label(nullptr) : QDialog(parent), m_save_entries(entries), m_entry(-1), m_entry_label(nullptr)
{ {
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Save Data Interface"));
if (op >= 8)
{
setWindowTitle(tr("Save Data Interface (Delete)"));
}
else if (op & 1)
{
setWindowTitle(tr("Save Data Interface (Load)"));
}
else
{
setWindowTitle(tr("Save Data Interface (Save)"));
}
setWindowIcon(QIcon(":/rpcs3.ico")); setWindowIcon(QIcon(":/rpcs3.ico"));
setMinimumSize(QSize(400, 400)); setMinimumSize(QSize(400, 400));
@ -47,7 +60,7 @@ save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& e
UpdateSelectionLabel(); UpdateSelectionLabel();
} }
if (is_saving) if (listSet->newData)
{ {
QPushButton *saveNewEntry = new QPushButton(tr("Save New Entry"), this); QPushButton *saveNewEntry = new QPushButton(tr("Save New Entry"), this);
connect(saveNewEntry, &QAbstractButton::clicked, this, [&]() connect(saveNewEntry, &QAbstractButton::clicked, this, [&]()

View File

@ -17,7 +17,7 @@ class save_data_list_dialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, bool is_saving, QWidget* parent = nullptr); explicit save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, u32 op, vm::ptr<CellSaveDataListSet>, QWidget* parent = nullptr);
s32 GetSelection(); s32 GetSelection();
private Q_SLOTS: private Q_SLOTS: