Handles directory creation in cellGameDataCheckCreate2 (#2488)

* Handle directory creation in cellGameDataCheckCreate2

Stops some games from displaying information about not enough memory on
hdd

* Returning CELL_OK causes some games to loop on sceNp functions

for "shaman magic"

* cellGameDataCheckCreate2 added param.sfo creating/rewriting

* fix fs::file null

and one readability change

* For debugging purposes

When fs::file problem is located will be improved

* Fixed wrong operators

* Conversion from vfs to fs

Should take care of fs::null

* Cleanup

removed some unnecessary logging

* Fix successive function calls

second call was always ending in error since it didn't create the conent
permission

* Changes according to Neko's review

* Change to use u32 value
This commit is contained in:
Inviuz 2017-03-11 09:59:50 +01:00 committed by Ivan
parent 309f409554
commit 40a84dd477
2 changed files with 46 additions and 18 deletions

View File

@ -405,6 +405,8 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
{
cellGame.error("cellGameDataCheckCreate2(version=0x%x, dirName=%s, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
//older sdk. it might not care about game type.
if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1)
{
return CELL_GAMEDATA_ERROR_PARAM;
@ -414,21 +416,15 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
const std::string& dir = "/dev_hdd0/game/"s + dirName.get_ptr();
if (!fs::is_dir(vfs::get(dir)))
{
cellGame.todo("cellGameDataCheckCreate2(): should create directory '%s'", dir);
// TODO: create data
return CELL_OK;
}
vm::var<CellGameDataCBResult> cbResult;
vm::var<CellGameDataStatGet> cbGet;
vm::var<CellGameDataStatSet> cbSet;
cbGet->isNewData = fs::is_dir(vfs::get(dir)) ? CELL_GAMEDATA_ISNEWDATA_NO : CELL_GAMEDATA_ISNEWDATA_YES;
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
cbGet->hddFreeSizeKB = 40000000; //40 GB
cbGet->isNewData = CELL_GAMEDATA_ISNEWDATA_NO;
strcpy_trunc(cbGet->contentInfoPath, dir);
strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR");
@ -448,23 +444,55 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
strcpy_trunc(cbGet->getParam.dataVersion, psf::get_string(sfo, "APP_VER", ""));
strcpy_trunc(cbGet->getParam.titleId, psf::get_string(sfo, "TITLE_ID", ""));
strcpy_trunc(cbGet->getParam.title, psf::get_string(sfo, "TITLE", ""));
// TODO: write lang titles
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
{
strcpy_trunc(cbGet->getParam.titleLang[i], psf::get_string(sfo, fmt::format("TITLE_%02d", i)));
}
funcStat(ppu, cbResult, cbGet, cbSet);
if (cbSet->setParam)
{
// TODO: write PARAM.SFO from cbSet
cellGame.todo("cellGameDataCheckCreate2(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam);
}
switch ((s32)cbResult->result)
{
case CELL_GAMEDATA_CBRESULT_OK_CANCEL:
// TODO: do not process game data
// TODO: do not process game data(directory)
cellGame.warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL");
return CELL_OK;
case CELL_GAMEDATA_CBRESULT_OK:
case CELL_GAMEDATA_CBRESULT_OK:
//game confirmed that it wants to create directory
if (!fs::is_dir(vfs::get(dir + "/USRDIR")) && !fs::create_path(vfs::get(dir + "/USRDIR")))
{
cellGame.error("cellGameDataCheckCreate2(): folder creation failed");
return CELL_GAME_ERROR_NOSPACE; //don't know which error. picked one at random
}
if (cbSet->setParam)
{
const auto vdir = vfs::get(dir);
//older SDK does not define not settable values, hopefully it doesn't just change some values(overwrite)
psf::registry sfo_write =
{
{ "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, cbSet->setParam->titleId) },
{ "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->title) },
{ "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, cbSet->setParam->dataVersion) },
{ "PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value() }
};
//sfo_write.emplace("PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value()); // I don't care about age restrictions.
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
{
sfo_write.emplace(fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->titleLang[i]));
}
if (!fs::is_dir(vdir))
{
cellGame.fatal("directory where param.sfo is to be created does not exist");
return CELL_GAME_ERROR_INTERNAL;
}
psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), sfo_write);
}
return CELL_OK;
case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result

View File

@ -31,7 +31,7 @@ s32 sceNpMatching2Init(u32 poolsize, s32 priority)
{
sceNp2.todo("sceNpMatching2Init(poolsize=0x%x, priority=%d)", poolsize, priority);
return CELL_OK;
return SCE_NP_MATCHING2_ERROR_TIMEDOUT;
}
s32 sceNpMatching2Init2(u32 poolsize, s32 priority, vm::ptr<SceNpMatching2UtilityInitParam> param)