Implement sys_game_process_exitspawn and fixes

This commit is contained in:
Raul Tambre 2014-12-14 19:14:26 +02:00
parent 24c5e7d6cd
commit b8d2343765
5 changed files with 155 additions and 70 deletions

View File

@ -62,7 +62,7 @@ public:
template<typename... Targs> __noinline void Success(const char* fmt, Targs... args) const template<typename... Targs> __noinline void Success(const char* fmt, Targs... args) const
{ {
LogOutput(LogSuccess, " : ", fmt::Format(fmt, args...)); LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...));
} }
template<typename... Targs> __noinline void Warning(const u32 id, const char* fmt, Targs... args) const template<typename... Targs> __noinline void Warning(const u32 id, const char* fmt, Targs... args) const

View File

@ -2,6 +2,7 @@
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/lv2/sys_process.h"
#include "Emu/FS/VFS.h" #include "Emu/FS/VFS.h"
#include "Utilities/rFile.h" #include "Utilities/rFile.h"
@ -187,15 +188,35 @@ int sceNpDrmGetTimelimit(u32 drm_path_addr, vm::ptr<u64> time_remain_usec)
return CELL_OK; return CELL_OK;
} }
int sceNpDrmProcessExitSpawn() int sceNpDrmProcessExitSpawn(vm::ptr<const char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{ {
UNIMPLEMENTED_FUNC(sceNp); sceNp->Warning("sceNpDrmProcessExitSpawn()");
sceNp->Warning("path: %s", path.get_ptr());
sceNp->Warning("argv: 0x%x", argv_addr);
sceNp->Warning("envp: 0x%x", envp_addr);
sceNp->Warning("data: 0x%x", data_addr);
sceNp->Warning("data_size: 0x%x", data_size);
sceNp->Warning("prio: %d", prio);
sceNp->Warning("flags: %d", flags);
sys_game_process_exitspawn(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
return CELL_OK; return CELL_OK;
} }
int sceNpDrmProcessExitSpawn2() int sceNpDrmProcessExitSpawn2(vm::ptr<const char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
{ {
UNIMPLEMENTED_FUNC(sceNp); sceNp->Warning("sceNpDrmProcessExitSpawn2()");
sceNp->Warning("path: %s", path.get_ptr());
sceNp->Warning("argv: 0x%x", argv_addr);
sceNp->Warning("envp: 0x%x", envp_addr);
sceNp->Warning("data: 0x%x", data_addr);
sceNp->Warning("data_size: 0x%x", data_size);
sceNp->Warning("prio: %d", prio);
sceNp->Warning("flags: %d", flags);
sys_game_process_exitspawn2(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
return CELL_OK; return CELL_OK;
} }

View File

@ -38,17 +38,20 @@ s32 sys_process_exit(s32 errorcode)
return CELL_OK; return CELL_OK;
} }
void sys_game_process_exitspawn( void sys_game_process_exitspawn(vm::ptr<const char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
vm::ptr<const char> path,
u32 argv_addr,
u32 envp_addr,
u32 data_addr,
u32 data_size,
u32 prio,
u64 flags )
{ {
std::string _path = path.get_ptr();
const std::string& from = "//";
const std::string& to = "/";
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
}
sys_process.Todo("sys_game_process_exitspawn()"); sys_process.Todo("sys_game_process_exitspawn()");
sys_process.Warning("path: %s", path.get_ptr()); sys_process.Warning("path: %s", _path.c_str());
sys_process.Warning("argv: 0x%x", argv_addr); sys_process.Warning("argv: 0x%x", argv_addr);
sys_process.Warning("envp: 0x%x", envp_addr); sys_process.Warning("envp: 0x%x", envp_addr);
sys_process.Warning("data: 0x%x", data_addr); sys_process.Warning("data: 0x%x", data_addr);
@ -60,25 +63,32 @@ void sys_game_process_exitspawn(
std::vector<std::string> argv; std::vector<std::string> argv;
std::vector<std::string> env; std::vector<std::string> env;
auto argvp = vm::ptr<vm::bptr<const char>>::make(argv_addr); if (argv_addr)
while (argvp && *argvp)
{ {
argv.push_back(argvp[0].get_ptr()); auto argvp = vm::ptr<vm::bptr<const char>>::make(argv_addr);
argvp++; while (argvp && *argvp)
} {
auto envp = vm::ptr<vm::bptr<const char>>::make(envp_addr); argv.push_back(argvp[0].get_ptr());
while (envp && *envp) argvp++;
{ }
env.push_back(envp[0].get_ptr());
envp++; for (auto &arg : argv) {
sys_process.Log("argument: %s", arg.c_str());
}
} }
for (auto &arg : argv) { if (envp_addr)
sys_process.Log("argument: %s", arg.c_str()); {
} auto envp = vm::ptr<vm::bptr<const char>>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
for (auto &en : env) { for (auto &en : env) {
sys_process.Log("env_argument: %s", en.c_str()); sys_process.Log("env_argument: %s", en.c_str());
}
} }
//TODO: execute the file in <path> with the args in argv //TODO: execute the file in <path> with the args in argv
@ -94,20 +104,32 @@ void sys_game_process_exitspawn(
Emu.Stop(); Emu.Stop();
}); });
int device = -1;
if (_path.substr(1, 8) == "dev_hdd0")
device = 0;
else if (_path.substr(1, 8) == "dev_hdd1")
device = 1;
Emu.BootGame(_path.c_str(), true, device);
return; return;
} }
void sys_game_process_exitspawn2( void sys_game_process_exitspawn2(vm::ptr<const char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
vm::ptr<const char> path,
u32 argv_addr,
u32 envp_addr,
u32 data_addr,
u32 data_size,
u32 prio,
u64 flags)
{ {
sys_process.Todo("sys_game_process_exitspawn2"); std::string _path = path.get_ptr();
sys_process.Warning("path: %s", path.get_ptr()); const std::string& from = "//";
const std::string& to = "/";
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
}
sys_process.Warning("sys_game_process_exitspawn2()");
sys_process.Warning("path: %s", _path.c_str());
sys_process.Warning("argv: 0x%x", argv_addr); sys_process.Warning("argv: 0x%x", argv_addr);
sys_process.Warning("envp: 0x%x", envp_addr); sys_process.Warning("envp: 0x%x", envp_addr);
sys_process.Warning("data: 0x%x", data_addr); sys_process.Warning("data: 0x%x", data_addr);
@ -115,29 +137,37 @@ void sys_game_process_exitspawn2(
sys_process.Warning("prio: %d", prio); sys_process.Warning("prio: %d", prio);
sys_process.Warning("flags: %d", flags); sys_process.Warning("flags: %d", flags);
std::string _path = path.get_ptr();
std::vector<std::string> argv; std::vector<std::string> argv;
std::vector<std::string> env; std::vector<std::string> env;
auto argvp = vm::ptr<vm::bptr<const char>>::make(argv_addr); if (argv_addr)
while (argvp && *argvp)
{ {
argv.push_back(argvp[0].get_ptr()); auto argvp = vm::ptr<vm::bptr<const char>>::make(argv_addr);
argvp++; while (argvp && *argvp)
} {
auto envp = vm::ptr<vm::bptr<const char>>::make(envp_addr); argv.push_back(argvp[0].get_ptr());
while (envp && *envp) argvp++;
{ }
env.push_back(envp[0].get_ptr());
envp++; for (auto &arg : argv)
{
sys_process.Log("argument: %s", arg.c_str());
}
} }
for (auto &arg : argv) { if (envp_addr)
sys_process.Log("argument: %s", arg.c_str()); {
} auto envp = vm::ptr<vm::bptr<const char>>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
for (auto &en : env) { for (auto &en : env)
sys_process.Log("env_argument: %s", en.c_str()); {
sys_process.Log("env_argument: %s", en.c_str());
}
} }
//TODO: execute the file in <path> with the args in argv //TODO: execute the file in <path> with the args in argv
@ -153,6 +183,15 @@ void sys_game_process_exitspawn2(
Emu.Stop(); Emu.Stop();
}); });
int device = -1;
if (_path.substr(1, 8) == "dev_hdd0")
device = 0;
else if (_path.substr(1, 8) == "dev_hdd1")
device = 1;
Emu.BootGame(_path.c_str(), true, device);
return; return;
} }

View File

@ -104,19 +104,20 @@ void Emulator::SetTitleID(const std::string& id)
void Emulator::CheckStatus() void Emulator::CheckStatus()
{ {
std::vector<CPUThread *>& threads = GetCPU().GetThreads(); std::vector<CPUThread *>& threads = GetCPU().GetThreads();
if(!threads.size()) if (!threads.size())
{ {
Stop(); Stop();
return; return;
} }
bool IsAllPaused = true; bool IsAllPaused = true;
for(u32 i=0; i<threads.size(); ++i) for (u32 i = 0; i < threads.size(); ++i)
{ {
if(threads[i]->IsPaused()) continue; if (threads[i]->IsPaused()) continue;
IsAllPaused = false; IsAllPaused = false;
break; break;
} }
if(IsAllPaused) if(IsAllPaused)
{ {
//ConLog.Warning("all paused!"); //ConLog.Warning("all paused!");
@ -125,20 +126,21 @@ void Emulator::CheckStatus()
} }
bool IsAllStoped = true; bool IsAllStoped = true;
for(u32 i=0; i<threads.size(); ++i) for (u32 i = 0; i < threads.size(); ++i)
{ {
if(threads[i]->IsStopped()) continue; if (threads[i]->IsStopped()) continue;
IsAllStoped = false; IsAllStoped = false;
break; break;
} }
if(IsAllStoped)
if (IsAllStoped)
{ {
//ConLog.Warning("all stoped!"); //ConLog.Warning("all stoped!");
Pause(); //Stop(); Pause(); //Stop();
} }
} }
bool Emulator::BootGame(const std::string& path) bool Emulator::BootGame(const std::string& path, bool direct, int device)
{ {
static const char* elf_path[6] = static const char* elf_path[6] =
{ {
@ -149,12 +151,35 @@ bool Emulator::BootGame(const std::string& path)
"/USRDIR/EBOOT.BIN", "/USRDIR/EBOOT.BIN",
"/EBOOT.BIN", "/EBOOT.BIN",
}; };
auto curpath = path;
for(int i=0; i<sizeof(elf_path) / sizeof(*elf_path);i++) if (!direct)
{ {
const std::string& curpath = path + elf_path[i]; for (int i = 0; i < sizeof(elf_path) / sizeof(*elf_path); i++)
{
curpath = path + elf_path[i];
if(rFile::Access(curpath, rFile::read)) if (rFile::Access(curpath, rFile::read))
{
SetPath(curpath);
Load();
return true;
}
}
}
else
{
std::string pathy;
if (device == 0)
Emu.GetVFS().GetDevice("dev_hdd0", pathy);
else if (device == 1)
Emu.GetVFS().GetDevice("dev_hdd1", pathy);
curpath = pathy.substr(0, pathy.length() - 9) + path;
if (rFile::Access(curpath, rFile::read))
{ {
SetPath(curpath); SetPath(curpath);
Load(); Load();
@ -170,9 +195,9 @@ void Emulator::Load()
{ {
GetModuleManager().init(); GetModuleManager().init();
if(!rExists(m_path)) return; if (!rExists(m_path)) return;
if(IsSelf(m_path)) if (IsSelf(m_path))
{ {
std::string elf_path = rFileName(m_path).GetPath(); std::string elf_path = rFileName(m_path).GetPath();
@ -185,7 +210,7 @@ void Emulator::Load()
elf_path += "/" + rFileName(m_path).GetName() + ".elf"; elf_path += "/" + rFileName(m_path).GetName() + ".elf";
} }
if(!DecryptSelf(elf_path, m_path)) if (!DecryptSelf(elf_path, m_path))
return; return;
m_path = elf_path; m_path = elf_path;
@ -197,7 +222,7 @@ void Emulator::Load()
LOG_NOTICE(LOADER, " "); //used to be skip_line LOG_NOTICE(LOADER, " "); //used to be skip_line
LOG_NOTICE(LOADER, "Mount info:"); LOG_NOTICE(LOADER, "Mount info:");
for(uint i=0; i<GetVFS().m_devices.size(); ++i) for (uint i = 0; i < GetVFS().m_devices.size(); ++i)
{ {
LOG_NOTICE(LOADER, "%s -> %s", GetVFS().m_devices[i]->GetPs3Path().c_str(), GetVFS().m_devices[i]->GetLocalPath().c_str()); LOG_NOTICE(LOADER, "%s -> %s", GetVFS().m_devices[i]->GetPs3Path().c_str(), GetVFS().m_devices[i]->GetLocalPath().c_str());
} }

View File

@ -195,7 +195,7 @@ public:
u32 GetCPUThreadStop() const { return m_cpu_thr_stop; } u32 GetCPUThreadStop() const { return m_cpu_thr_stop; }
void CheckStatus(); void CheckStatus();
bool BootGame(const std::string& path); bool BootGame(const std::string& path, bool direct = false, int device = 0);
void Load(); void Load();
void Run(); void Run();