diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index 13908a106b..f28863be8c 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -595,7 +595,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u return CELL_GCM_ERROR_INVALID_VALUE; } - if (offset & 0xffff || size & 0xffff || pitch & 0xf) + if (offset & 0xffff || size & 0xffff || pitch & 0xff) { cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; @@ -603,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) { - cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM"); return CELL_GCM_ERROR_INVALID_ENUM; } @@ -1171,7 +1171,7 @@ s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segment const auto& put = vm::_ref(m_config->gcm_info.control_addr).put; const auto& get = vm::_ref(m_config->gcm_info.control_addr).get; - if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2) + if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000) { return CELL_GCM_ERROR_FAILURE; } @@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co return CELL_GCM_ERROR_INVALID_VALUE; } - if (offset & 0xffff || size & 0xffff || pitch & 0xf) + if (offset & 0xffff || size & 0xffff || pitch & 0xff) { cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; @@ -1485,4 +1485,4 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []() // Special REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN; -}); \ No newline at end of file +}); diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index f6d0bfe195..48b2080486 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -8,6 +8,7 @@ #include "Crypto/unself.h" #include "cellRtc.h" #include "sceNp.h" +#include "cellSysutil.h" logs::channel sceNp("sceNp"); @@ -905,13 +906,23 @@ s32 sceNpLookupTitleSmallStorageAsync() s32 sceNpManagerRegisterCallback(vm::ptr callback, vm::ptr arg) { - sceNp.todo("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg); + sceNp.warning("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg); if (!callback) { return SCE_NP_ERROR_INVALID_ARGUMENT; } + sysutil_register_cb([=](ppu_thread& ppu)->s32 + { + callback(ppu, SCE_NP_MANAGER_STATUS_OFFLINE, CELL_OK, arg.addr()); + return CELL_OK; + }); + + // TODO: + // * Save the callback somewhere for future updates once network is implemented + // * If register is called again, created cb needs to be canceled + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 82409777f5..acc9ae0547 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -557,9 +557,14 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p verify(HERE), !fs::get_virtual_device(path); rXmlDocument doc; doc.Load(path); + auto trophy_base = doc.GetRoot(); + if (trophy_base->GetChildren()->GetName() == "trophyconf") + { + trophy_base = trophy_base->GetChildren(); + } bool found = false; - for (std::shared_ptr n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) { + for (std::shared_ptr n = trophy_base->GetChildren(); n; n = n->GetNext()) { if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str()))) { found = true; diff --git a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp index b1a54a349c..6736bcb69f 100644 --- a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp @@ -53,12 +53,14 @@ s32 sys_get_random_number(vm::ptr addr, u64 size) { sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size); - if (size > 4096) - size = 4096; - - for (u32 i = 0; i < (u32)size - 1; i++) + if (size > 0x1000) { - addr[i] = rand() % 256; + return CELL_EINVAL; + } + + for (u32 i = 0; i < (u32)size; i++) + { + addr[i] = rand() & 0xff; } return CELL_OK; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 4486b051cd..b489bea73d 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -280,15 +280,16 @@ void ppu_thread::on_init(const std::shared_ptr& _this) if (!stack_addr) { // Allocate stack + gap between stacks - const_cast(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096; - - if (!stack_addr) + auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack); + if (!new_stack_base) { fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size); } + const_cast(stack_addr) = new_stack_base + 4096; + // Make the gap inaccessible - vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable); + vm::page_protect(new_stack_base, 4096, 0, 0, vm::page_readable + vm::page_writable); gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200; diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index 914f88a8d6..fb503d8d3f 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -9,9 +9,9 @@ bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configp { const std::string& path = vfs::get(filepath); - if (!fs::is_file(path)) + if (!Generate(filepath, configpath)) { - Generate(filepath, configpath); + return false; } if (!m_file.open(path, fs::read)) @@ -147,7 +147,13 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con m_table4.clear(); m_table6.clear(); - for (std::shared_ptr n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) + auto trophy_base = doc.GetRoot(); + if (trophy_base->GetChildren()->GetName() == "trophyconf") + { + trophy_base = trophy_base->GetChildren(); + } + + for (std::shared_ptr n = trophy_base->GetChildren(); n; n = n->GetNext()) { if (n->GetName() == "trophy") { diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index da6bea24bb..fe43740d03 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -22,7 +22,7 @@ bool TRPLoader::Install(const std::string& dest, bool show) return false; } - std::vector buffer; buffer.reserve(65536); + std::vector buffer(65536); for (const TRPEntry& entry : m_entries) {