From 24d3e2b2b81613cff0ebe3bffcc2f464d6afb730 Mon Sep 17 00:00:00 2001 From: Eladash Date: Fri, 21 Feb 2020 18:09:41 +0200 Subject: [PATCH] cellGameDataCheckCreate(2): More improvements * IsNewData is false only if PARAM.SFO exists. * Don't create directory on error (setParam == nullptr && isNewData). * Return CELL_GAMEDATA_ERROR_BROKEN if PARAM.SFO exists on target directory yet is not from GD category. --- rpcs3/Emu/Cell/Modules/cellGame.cpp | 56 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 44f0ad7b95..e159e2e18c 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -541,20 +541,28 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr // TODO: output errors (errDialog) const std::string dir = "/dev_hdd0/game/"s + dirName.get_ptr(); + const std::string usrdir = dir + "/USRDIR"; vm::var cbResult; vm::var cbGet; vm::var cbSet; - const u32 new_data = fs::is_dir(vfs::get(dir)) ? CELL_GAMEDATA_ISNEWDATA_NO : CELL_GAMEDATA_ISNEWDATA_YES; + psf::registry sfo = psf::load_object(fs::file(vfs::get(dir + "/PARAM.SFO"))); + + const u32 new_data = sfo.empty() && !fs::is_file(vfs::get(dir + "/PARAM.SFO")) ? CELL_GAMEDATA_ISNEWDATA_YES : CELL_GAMEDATA_ISNEWDATA_NO; + + if (!new_data && psf::get_string(sfo, "CATEGORY", "") != "GD") + { + return CELL_GAMEDATA_ERROR_BROKEN; + } + cbGet->isNewData = new_data; // TODO: Use the free space of the computer's HDD where RPCS3 is being run. cbGet->hddFreeSizeKB = 40 * 1024 * 1024 - 1; // Read explanation in cellHddGameCheck - strcpy_trunc(cbGet->contentInfoPath, dir); - strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR"); + strcpy_trunc(cbGet->gameDataPath, usrdir); // TODO: set correct time cbGet->st_atime_ = 0; @@ -565,8 +573,6 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC; cbGet->sysSizeKB = 0; // TODO - psf::registry sfo = psf::load_object(fs::file(vfs::get(dir + "/PARAM.SFO"))); - cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL; cbGet->getParam.parentalLevel = psf::get_integer(sfo, "PARENTAL_LEVEL", 0); strcpy_trunc(cbGet->getParam.dataVersion, psf::get_string(sfo, "APP_VER", "")); @@ -591,21 +597,28 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr case CELL_GAMEDATA_CBRESULT_OK: { // Game confirmed that it wants to create directory - const std::string usrdir = dir + "/USRDIR"; - const std::string vusrdir = vfs::get(usrdir); + const auto setParam = cbSet->setParam; - if (new_data && !fs::create_path(vusrdir)) + if (new_data) { - return {CELL_GAME_ERROR_ACCESS_ERROR, usrdir}; + if (!setParam) + { + return CELL_GAMEDATA_ERROR_PARAM; + } + + if (!fs::create_path(vfs::get(usrdir))) + { + return {CELL_GAME_ERROR_ACCESS_ERROR, usrdir}; + } } - if (cbSet->setParam) + if (setParam) { psf::assign(sfo, "CATEGORY", psf::string(3, "GD")); - psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, cbSet->setParam->titleId)); - psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->title)); - psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, cbSet->setParam->dataVersion)); - psf::assign(sfo, "PARENTAL_LEVEL", cbSet->setParam->parentalLevel.value()); + psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, setParam->titleId)); + psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->title)); + psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, setParam->dataVersion)); + psf::assign(sfo, "PARENTAL_LEVEL", +setParam->parentalLevel); for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++) { @@ -614,21 +627,10 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr continue; } - psf::assign(sfo, fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, cbSet->setParam->titleLang[i])); + psf::assign(sfo, fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->titleLang[i])); } - const auto vdir = vfs::get(dir); - - if (!fs::is_dir(vdir)) - { - return {CELL_GAME_ERROR_INTERNAL, dir}; - } - - psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), sfo); - } - else if (new_data) - { - return CELL_GAMEDATA_ERROR_PARAM; + psf::save_object(fs::file(vfs::get(dir + "/PARAM.SFO"), fs::rewrite), sfo); } return CELL_OK;