diff --git a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp index 359f593dac..ad15f68a2f 100644 --- a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp @@ -1,13 +1,23 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/IdManager.h" +#include "Emu/System.h" #include "cellGame.h" LOG_CHANNEL(cellGameExec); +struct game_exec_data +{ + atomic_t execdata = 0; // TODO: pass this to the source application after closing the current application +}; + error_code cellGameSetExitParam(u32 execdata) { cellGameExec.todo("cellGameSetExitParam(execdata=0x%x)", execdata); + + g_fxo->get().execdata = execdata; + return CELL_OK; } @@ -25,9 +35,17 @@ error_code cellGameGetHomeDataExportPath(vm::ptr exportPath) return CELL_GAME_ERROR_NOAPP; } -error_code cellGameGetHomePath() +error_code cellGameGetHomePath(vm::ptr homePath) { - UNIMPLEMENTED_FUNC(cellGameExec); + cellGameExec.todo("cellGameGetHomePath(homePath=*0x%x)", homePath); + + if (!homePath) + { + return CELL_GAME_ERROR_PARAM; + } + + // TODO: PlayStation home is defunct. + return CELL_OK; } @@ -64,6 +82,12 @@ error_code cellGameExecGame() return CELL_OK; } +error_code cellGameDeleteGame() +{ + UNIMPLEMENTED_FUNC(cellGameExec); + return CELL_OK; +} + error_code cellGameGetBootGameInfo(vm::ptr type, vm::ptr dirName, vm::ptr execdata) { cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execdata=*0x%x)", type, dirName, execdata); @@ -73,8 +97,26 @@ error_code cellGameGetBootGameInfo(vm::ptr type, vm::ptr dirName, vm: return CELL_GAME_ERROR_PARAM; } - // TODO: Support more boot types - *type = CELL_GAME_GAMETYPE_SYS; + const u32 source_type = Emu.GetBootSourceType(); + + *type = source_type; + + if (execdata) + { + *execdata = g_fxo->get().execdata; + } + + if (source_type == CELL_GAME_GAMETYPE_HDD) + { + const std::string dir_name = Emu.GetDir(); + + if (dir_name.size() >= CELL_GAME_DIRNAME_SIZE) + { + return CELL_HDDGAME_ERROR_INTERNAL; // Speculative + } + + std::memcpy(dirName.get_ptr(), dir_name.c_str(), dir_name.size() + 1); + } return CELL_OK; } @@ -87,5 +129,6 @@ DECLARE(ppu_module_manager::cellGameExec)("cellGameExec", []() REG_FUNC(cellGameExec, cellGameGetHomeDataImportPath); REG_FUNC(cellGameExec, cellGameGetHomeLaunchOptionPath); REG_FUNC(cellGameExec, cellGameExecGame); + REG_FUNC(cellGameExec, cellGameDeleteGame); REG_FUNC(cellGameExec, cellGameGetBootGameInfo); }); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index c530c97072..b71b11b01f 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -19,6 +19,7 @@ #include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/lv2/sys_prx.h" #include "Emu/Cell/lv2/sys_overlay.h" +#include "Emu/Cell/Modules/cellGame.h" #include "Emu/title.h" #include "Emu/IdManager.h" @@ -560,6 +561,29 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool { const std::string resolved_path = GetCallbacks().resolve_path(m_path); + if (m_config_mode == cfg_mode::continuous) + { + // The program is being booted from another running program + // CELL_GAME_GAMETYPE_GAMEDATA is not used as boot type + + if (m_cat == "DG"sv) + { + m_boot_source_type = CELL_GAME_GAMETYPE_DISC; + } + else if (m_cat == "HM"sv) + { + m_boot_source_type = CELL_GAME_GAMETYPE_HOME; + } + else + { + m_boot_source_type = CELL_GAME_GAMETYPE_HDD; + } + } + else + { + m_boot_source_type = CELL_GAME_GAMETYPE_SYS; + } + if (!IsStopped()) { Kill(); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 75cdb507b5..40f7def741 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -180,6 +180,13 @@ public: std::string disc; std::string hdd1; + u32 m_boot_source_type = 0; // CELL_GAME_GAMETYPE_SYS + + const u32& GetBootSourceType() const + { + return m_boot_source_type; + } + const std::string& GetBoot() const { return m_path;