mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
Added fxm::withdraw, cellGame improved
This commit is contained in:
parent
6f3c50eba2
commit
544fe531a3
2
bin/dev_hdd1/cache/README.txt
vendored
2
bin/dev_hdd1/cache/README.txt
vendored
@ -1 +1 @@
|
|||||||
every Folder in this directory gets cleared when cellSysCacheClear() is called, so don't store important data here
|
This directory is used for cache functionality, so don't store any data here.
|
||||||
|
1
bin/dev_hdd1/game/README.txt
Normal file
1
bin/dev_hdd1/game/README.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
This directory is used for temporary gamedata functionality, so don't store any data here.
|
@ -269,6 +269,21 @@ namespace fxm
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add fixed object of specified type, replacing previous one if it exists
|
||||||
|
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, std::shared_ptr<T>> make_always(Args&&... args)
|
||||||
|
{
|
||||||
|
extern std::mutex g_fx_mutex;
|
||||||
|
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||||
|
|
||||||
|
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
g_fx_map[typeid(T)] = ptr;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
// check whether the object exists
|
// check whether the object exists
|
||||||
template<typename T> bool check()
|
template<typename T> bool check()
|
||||||
{
|
{
|
||||||
@ -315,4 +330,24 @@ namespace fxm
|
|||||||
|
|
||||||
return g_fx_map.erase(found), true;
|
return g_fx_map.erase(found), true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove fixed object created with type T and return it
|
||||||
|
template<typename T> std::shared_ptr<T> withdraw()
|
||||||
|
{
|
||||||
|
extern std::mutex g_fx_mutex;
|
||||||
|
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||||
|
|
||||||
|
const auto found = g_fx_map.find(typeid(T));
|
||||||
|
|
||||||
|
if (found == g_fx_map.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = std::static_pointer_cast<T>(std::move(found->second));
|
||||||
|
|
||||||
|
return g_fx_map.erase(found), ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
#include "Emu/IdManager.h"
|
||||||
#include "Emu/SysCalls/Modules.h"
|
#include "Emu/SysCalls/Modules.h"
|
||||||
|
|
||||||
#include "Utilities/rMsgBox.h"
|
#include "Utilities/rMsgBox.h"
|
||||||
@ -12,9 +13,45 @@
|
|||||||
|
|
||||||
extern Module cellGame;
|
extern Module cellGame;
|
||||||
|
|
||||||
std::string contentInfo;
|
// Specified as second content_permission_t constructor argument to inform temporary directory
|
||||||
std::string usrdir;
|
static struct temporary_content_dir_tag_t{} const temporary_content_dir_tag{};
|
||||||
bool path_set = false;
|
|
||||||
|
// Normal content directory (if is_temporary is not involved):
|
||||||
|
// contentInfo = dir
|
||||||
|
// usrdir = dir + "/USRDIR"
|
||||||
|
// Temporary content directory:
|
||||||
|
// contentInfo = "/dev_hdd1/game/" + dir
|
||||||
|
// usrdir = "/dev_hdd1/game/" + dir + "/USRDIR"
|
||||||
|
// Usual (persistent) content directory (if is_temporary):
|
||||||
|
// contentInfo = "/dev_hdd0/game/" + dir
|
||||||
|
// usrdir = "/dev_hdd0/game/" + dir + "/USRDIR"
|
||||||
|
struct content_permission_t final
|
||||||
|
{
|
||||||
|
// content directory name or path
|
||||||
|
const std::string dir;
|
||||||
|
|
||||||
|
// true if temporary directory is created and must be moved or deleted
|
||||||
|
bool is_temporary = false;
|
||||||
|
|
||||||
|
content_permission_t(const std::string& dir)
|
||||||
|
: dir(dir)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
content_permission_t(const std::string& dir, const temporary_content_dir_tag_t&)
|
||||||
|
: dir(dir)
|
||||||
|
, is_temporary(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~content_permission_t()
|
||||||
|
{
|
||||||
|
if (is_temporary)
|
||||||
|
{
|
||||||
|
// TODO: delete temporary directory and all its contents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
|
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
|
||||||
{
|
{
|
||||||
@ -155,19 +192,23 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||||||
*type = CELL_GAME_GAMETYPE_DISC;
|
*type = CELL_GAME_GAMETYPE_DISC;
|
||||||
*attributes = 0; // TODO
|
*attributes = 0; // TODO
|
||||||
if (dirName) strcpy_trunc(*dirName, ""); // ???
|
if (dirName) strcpy_trunc(*dirName, ""); // ???
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
|
||||||
path_set = true;
|
{
|
||||||
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (category.substr(0, 2) == "HG")
|
else if (category.substr(0, 2) == "HG")
|
||||||
{
|
{
|
||||||
std::string titleId = psf.GetString("TITLE_ID");
|
std::string titleId = psf.GetString("TITLE_ID");
|
||||||
*type = CELL_GAME_GAMETYPE_HDD;
|
*type = CELL_GAME_GAMETYPE_HDD;
|
||||||
*attributes = 0; // TODO
|
*attributes = 0; // TODO
|
||||||
if (dirName) strcpy_trunc(*dirName, titleId);
|
if (dirName) strcpy_trunc(*dirName, titleId);
|
||||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
|
||||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + titleId))
|
||||||
path_set = true;
|
{
|
||||||
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (category.substr(0, 2) == "GD")
|
else if (category.substr(0, 2) == "GD")
|
||||||
{
|
{
|
||||||
@ -175,9 +216,11 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||||||
*type = CELL_GAME_GAMETYPE_DISC;
|
*type = CELL_GAME_GAMETYPE_DISC;
|
||||||
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
|
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
|
||||||
if (dirName) strcpy_trunc(*dirName, titleId); // ???
|
if (dirName) strcpy_trunc(*dirName, titleId); // ???
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
|
||||||
path_set = true;
|
{
|
||||||
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (psf)
|
else if (psf)
|
||||||
{
|
{
|
||||||
@ -216,12 +259,12 @@ s32 cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> reserved
|
|||||||
return CELL_GAME_ERROR_NOTPATCH;
|
return CELL_GAME_ERROR_NOTPATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string titleId = psf.GetString("TITLE_ID");
|
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + psf.GetString("TITLE_ID")))
|
||||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
{
|
||||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
return CELL_GAME_ERROR_BUSY;
|
||||||
path_set = true;
|
}
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentSize> size)
|
s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentSize> size)
|
||||||
@ -251,15 +294,13 @@ s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentS
|
|||||||
if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME"))
|
if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME"))
|
||||||
{
|
{
|
||||||
cellGame.Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found");
|
cellGame.Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found");
|
||||||
contentInfo = "";
|
|
||||||
usrdir = "";
|
|
||||||
path_set = true;
|
|
||||||
return CELL_GAME_RET_NONE;
|
return CELL_GAME_RET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
{
|
||||||
path_set = true;
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -268,15 +309,13 @@ s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentS
|
|||||||
if (!Emu.GetVFS().ExistsDir(dir))
|
if (!Emu.GetVFS().ExistsDir(dir))
|
||||||
{
|
{
|
||||||
cellGame.Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str());
|
cellGame.Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str());
|
||||||
contentInfo = "";
|
|
||||||
usrdir = "";
|
|
||||||
path_set = true;
|
|
||||||
return CELL_GAME_RET_NONE;
|
return CELL_GAME_RET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentInfo = dir;
|
if (!fxm::make<content_permission_t>(dir))
|
||||||
usrdir = dir + "/USRDIR";
|
{
|
||||||
path_set = true;
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_GAME_RET_OK;
|
||||||
@ -291,32 +330,40 @@ s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
|||||||
return CELL_GAME_ERROR_PARAM;
|
return CELL_GAME_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
cellGame.Warning("cellGameContentPermit(): path_set=%d, contentInfo='%s', usrdir='%s'", path_set, contentInfo, usrdir);
|
const auto path_set = fxm::withdraw<content_permission_t>();
|
||||||
|
|
||||||
if (!path_set)
|
if (!path_set)
|
||||||
{
|
{
|
||||||
return CELL_GAME_ERROR_FAILURE;
|
return CELL_GAME_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentInfo.size() == 9 && usrdir.empty())
|
if (path_set->is_temporary)
|
||||||
{
|
{
|
||||||
if (Emu.GetVFS().RenameDir("/dev_hdd0/game/TMP_" + contentInfo, "/dev_hdd0/game/" + contentInfo))
|
const std::string dir = "/dev_hdd0/game/" + path_set->dir;
|
||||||
|
|
||||||
|
// make temporary directory persistent
|
||||||
|
if (Emu.GetVFS().RenameDir("/dev_hdd1/game/" + path_set->dir, dir))
|
||||||
{
|
{
|
||||||
cellGame.Success("cellGameContentPermit(): gamedata directory created ('/dev_hdd0/game/%s')", contentInfo);
|
cellGame.Success("cellGameContentPermit(): '%s' directory created", dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Cannot create gamedata directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
contentInfo = "/dev_hdd0/game/" + contentInfo;
|
// prevent deleting directory
|
||||||
usrdir = contentInfo + "/USRDIR";
|
path_set->is_temporary = false;
|
||||||
|
|
||||||
|
strcpy_trunc(*contentInfoPath, dir);
|
||||||
|
strcpy_trunc(*usrdirPath, dir + "/USRDIR");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy_trunc(*contentInfoPath, path_set->dir);
|
||||||
|
strcpy_trunc(*usrdirPath, path_set->dir + "/USRDIR");
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy_trunc(*contentInfoPath, contentInfo);
|
|
||||||
strcpy_trunc(*usrdirPath, usrdir);
|
|
||||||
|
|
||||||
contentInfo = "";
|
|
||||||
usrdir = "";
|
|
||||||
path_set = false;
|
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||||
@ -429,8 +476,8 @@ s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CEL
|
|||||||
cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath);
|
cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath);
|
||||||
|
|
||||||
std::string dir = init->titleId;
|
std::string dir = init->titleId;
|
||||||
std::string tmp_contentInfo = "/dev_hdd0/game/TMP_" + dir;
|
std::string tmp_contentInfo = "/dev_hdd1/game/" + dir;
|
||||||
std::string tmp_usrdir = "/dev_hdd0/game/TMP_" + dir + "/USRDIR";
|
std::string tmp_usrdir = "/dev_hdd1/game/" + dir + "/USRDIR";
|
||||||
|
|
||||||
if (!Emu.GetVFS().CreateDir(tmp_contentInfo))
|
if (!Emu.GetVFS().CreateDir(tmp_contentInfo))
|
||||||
{
|
{
|
||||||
@ -444,14 +491,15 @@ s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CEL
|
|||||||
return CELL_GAME_ERROR_ACCESS_ERROR; // ???
|
return CELL_GAME_ERROR_ACCESS_ERROR; // ???
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fxm::make<content_permission_t>(dir, temporary_content_dir_tag))
|
||||||
|
{
|
||||||
|
return CELL_GAME_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
|
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
|
||||||
strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo);
|
strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo);
|
||||||
strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
|
strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
|
||||||
|
|
||||||
contentInfo = dir;
|
|
||||||
usrdir.clear();
|
|
||||||
path_set = true;
|
|
||||||
|
|
||||||
cellGame.Success("cellGameCreateGameData(): temporary gamedata directory created ('%s')", tmp_contentInfo);
|
cellGame.Success("cellGameCreateGameData(): temporary gamedata directory created ('%s')", tmp_contentInfo);
|
||||||
|
|
||||||
// TODO: set initial PARAM.SFO parameters
|
// TODO: set initial PARAM.SFO parameters
|
||||||
@ -665,10 +713,6 @@ void cellSysutil_GameData_init()
|
|||||||
|
|
||||||
Module cellGame("cellGame", []()
|
Module cellGame("cellGame", []()
|
||||||
{
|
{
|
||||||
contentInfo = "";
|
|
||||||
usrdir = "";
|
|
||||||
path_set = false;
|
|
||||||
|
|
||||||
REG_FUNC(cellGame, cellGameBootCheck);
|
REG_FUNC(cellGame, cellGameBootCheck);
|
||||||
REG_FUNC(cellGame, cellGamePatchCheck);
|
REG_FUNC(cellGame, cellGamePatchCheck);
|
||||||
REG_FUNC(cellGame, cellGameDataCheck);
|
REG_FUNC(cellGame, cellGameDataCheck);
|
||||||
|
Loading…
Reference in New Issue
Block a user