mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Minor changes for save data utility (#3005)
This commit is contained in:
parent
aed9b31294
commit
6610abcd5f
3 changed files with 107 additions and 46 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
#include "cellSaveData.h"
|
||||
|
||||
|
@ -63,7 +64,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
|
||||
{
|
||||
// TODO: check arguments
|
||||
|
||||
std::unique_lock<std::mutex> lock(g_savedata_mutex, std::try_to_lock);
|
||||
|
||||
if (!lock)
|
||||
|
@ -82,6 +82,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
vm::ptr<CellSaveDataFileGet> fileGet = g_savedata_context.ptr(&savedata_context::fileGet);
|
||||
vm::ptr<CellSaveDataFileSet> fileSet = g_savedata_context.ptr(&savedata_context::fileSet);
|
||||
|
||||
//TODO: get current user ID
|
||||
// userId(0) = CELL_SYSUTIL_USERID_CURRENT
|
||||
// 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));
|
||||
|
||||
|
@ -100,6 +102,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
|
||||
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
|
||||
|
||||
// get the saves matching the supplied prefix
|
||||
for (const auto& entry : fs::dir(base_dir))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
|
@ -211,13 +214,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: display dialog
|
||||
cellSaveData.warning("savedata_op(): funcList returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
// if the callback has returned ok, lets return OK.
|
||||
// typically used at game launch when no list is actually required.
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
// CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -236,6 +241,16 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
return true;
|
||||
}), 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
|
||||
s32 focused = -1;
|
||||
|
||||
|
@ -296,6 +311,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
}
|
||||
case CELL_SAVEDATA_FOCUSPOS_NEWDATA:
|
||||
{
|
||||
//TODO: If adding the new data to the save_entries vector
|
||||
// to be displayed in the save mangaer UI, it should be focused here
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -339,8 +356,19 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
// Fixed Callback
|
||||
funcFixed(ppu, result, listGet, fixedSet);
|
||||
|
||||
// skip all following steps if OK_LAST
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: Show msgDialog if required
|
||||
// depends on fixedSet->option
|
||||
// 0 = none
|
||||
// 1 = skip confirmation dialog
|
||||
|
||||
cellSaveData.warning("savedata_op(): funcFixed returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
@ -363,10 +391,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
{
|
||||
save_entry.dirName = fixedSet->dirName.get_ptr();
|
||||
}
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (selected >= 0)
|
||||
|
@ -479,6 +504,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (statSet->setParam)
|
||||
{
|
||||
// Update PARAM.SFO
|
||||
|
@ -498,18 +528,20 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
{ "TITLE", psf::string(128, statSet->setParam->title) },
|
||||
});
|
||||
}
|
||||
else if (psf.empty())
|
||||
{
|
||||
// setParam is NULL for new savedata: abort operation
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
//else if (psf.empty())
|
||||
//{
|
||||
// // setParam is specified if something required updating.
|
||||
// // Do not exit. Recreate mode will handle the rest
|
||||
// //return CELL_OK;
|
||||
//}
|
||||
|
||||
switch (const u32 mode = statSet->reCreateMode & 0xffff)
|
||||
{
|
||||
case CELL_SAVEDATA_RECREATE_NO:
|
||||
{
|
||||
cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
//CELL_SAVEDATA_RECREATE_NO = overwrite and let the user know, not data is corrupt.
|
||||
//cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
//TODO: if this is a save, and it's not auto, then show a dialog
|
||||
// fallthrough
|
||||
}
|
||||
|
||||
|
@ -521,7 +553,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
case CELL_SAVEDATA_RECREATE_YES:
|
||||
case CELL_SAVEDATA_RECREATE_YES_RESET_OWNER:
|
||||
{
|
||||
// TODO?
|
||||
|
||||
// TODO: Only delete data, not owner info
|
||||
for (const auto& entry : fs::dir(dir_path))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
|
@ -530,12 +563,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: probably not deleting owner info
|
||||
if (!statSet->setParam)
|
||||
{
|
||||
// Savedata deleted and setParam is NULL: delete directory and abort operation
|
||||
if (fs::remove_dir(dir_path)) cellSaveData.error("savedata_op(): savedata directory %s deleted", save_entry.dirName);
|
||||
|
||||
return CELL_OK;
|
||||
//return CELL_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -549,16 +583,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
}
|
||||
}
|
||||
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
// Create save directory if necessary
|
||||
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
|
||||
{
|
||||
// Let's ignore this error for now
|
||||
{
|
||||
cellSaveData.warning("savedata_op(): failed to create %s", dir_path);
|
||||
return CELL_SAVEDATA_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
// Enter the loop where the save files are read/created/deleted
|
||||
|
@ -578,9 +609,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
|
||||
{
|
||||
//todo: display user prompt
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: Show progress
|
||||
// if it's not an auto load/save
|
||||
|
||||
std::string file_path;
|
||||
|
||||
switch (const u32 type = fileSet->fileType)
|
||||
|
@ -681,6 +716,51 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
|
||||
{
|
||||
|
||||
//TODO: accurately get the current user
|
||||
if (userId == 0)
|
||||
{
|
||||
userId = 1u;
|
||||
}
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/%s/", userId, dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
fs::stat_t dir_info{};
|
||||
if (!fs::stat(save_path, dir_info))
|
||||
{
|
||||
return CELL_SAVEDATA_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// get file stats, namely directory
|
||||
strcpy_trunc(dir->dirName, dirName.get_ptr());
|
||||
dir->atime = dir_info.atime;
|
||||
dir->ctime = dir_info.ctime;
|
||||
dir->mtime = dir_info.mtime;
|
||||
|
||||
//TODO: Set bind in accordance to any problems
|
||||
*bind = 0;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Functions
|
||||
s32 cellSaveDataListSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
|
@ -949,27 +1029,8 @@ s32 cellSaveDataFixedExport(ppu_thread& ppu, vm::cptr<char> dirName, u32 maxSize
|
|||
s32 cellSaveDataGetListItem(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
|
||||
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/00000001/savedata/%s/", dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
|
||||
}
|
||||
|
||||
s32 cellSaveDataUserListDelete(ppu_thread& ppu, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
|
||||
|
@ -1009,9 +1070,9 @@ s32 cellSaveDataUserFixedExport(ppu_thread& ppu, u32 userId, vm::cptr<char> dirN
|
|||
|
||||
s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSaveData);
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
|
||||
return CELL_OK;
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
}
|
||||
|
||||
void cellSysutil_SaveData_init()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue