vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::cptr<char> source, u32 len) { sysPrxForUser.trace("_sys_strncat(dest=*0x%x, source=%s, len=%d)", dest, source, len); verify(HERE), std::strncat(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr(); return dest; }
vm::ptr<char> _sys_strcpy(vm::ptr<char> dest, vm::cptr<char> source) { sysPrxForUser.trace("_sys_strcpy(dest=*0x%x, source=%s)", dest, source); verify(HERE), std::strcpy(dest.get_ptr(), source.get_ptr()) == dest.get_ptr(); return dest; }
s32 sys_fs_opendir(vm::cptr<char> path, vm::ptr<u32> fd) { sys_fs.Warning("sys_fs_opendir(path=*0x%x, fd=*0x%x)", path, fd); sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::shared_ptr<vfsDirBase> dir(Emu.GetVFS().OpenDir(path.get_ptr())); if (!dir || !dir->IsOpened()) { sys_fs.Error("sys_fs_opendir('%s'): failed to open directory", path.get_ptr()); return CELL_FS_ENOENT; } *fd = Emu.GetIdManager().make<lv2_dir_t>(std::move(dir)); return CELL_OK; }
vm::ptr<void> _sys_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size) { sysPrxForUser.Log("_sys_memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); memcpy(dst.get_ptr(), src.get_ptr(), size); return dst; }
vm::ptr<void> _sys_memmove(vm::ptr<void> dst, vm::cptr<void> src, u32 size) { sysPrxForUser.trace("_sys_memmove(dst=*0x%x, src=*0x%x, size=%d)", dst, src, size); std::memmove(dst.get_ptr(), src.get_ptr(), size); return dst; }
s32 sys_prx_get_module_id_by_name(vm::cptr<char> name, u64 flags, vm::ptr<sys_prx_get_module_id_by_name_option_t> pOpt) { const char *realName = name.get_ptr(); sys_prx.todo("sys_prx_get_module_id_by_name(name=%s, flags=%d, pOpt=*0x%x)", realName, flags, pOpt); //if (realName == "?") ... return CELL_PRX_ERROR_UNKNOWN_MODULE; }
s32 cellFsAioInit(vm::cptr<char> mount_point) { cellFs.Warning("cellFsAioInit(mount_point=*0x%x)", mount_point); cellFs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); // TODO: create AIO thread (if not exists) for specified mount point return CELL_OK; }
s32 cellFsAioFinish(vm::cptr<char> mount_point) { cellFs.Warning("cellFsAioFinish(mount_point=*0x%x)", mount_point); cellFs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); // TODO: delete existing AIO thread for specified mount point return CELL_OK; }
s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentSize> size) { cellGame.Warning("cellGameDataCheck(type=%d, dirName=*0x%x, size=*0x%x)", type, dirName, size); if ((type - 1) >= 3) { cellGame.Error("cellGameDataCheck(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; } if (size) { // TODO: Use the free space of the computer's HDD where RPCS3 is being run. size->hddFreeSizeKB = 40000000; //40 GB // TODO: Calculate data size for game data, if necessary. size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; size->sysSizeKB = 0; } if (type == CELL_GAME_GAMETYPE_DISC) { // TODO: not sure what should be checked there if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME")) { cellGame.Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found"); contentInfo = ""; usrdir = ""; path_set = true; return CELL_GAME_RET_NONE; } contentInfo = "/dev_bdvd/PS3_GAME"; usrdir = "/dev_bdvd/PS3_GAME/USRDIR"; path_set = true; } else { const std::string dir = std::string("/dev_hdd0/game/") + dirName.get_ptr(); if (!Emu.GetVFS().ExistsDir(dir)) { cellGame.Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str()); contentInfo = ""; usrdir = ""; path_set = true; return CELL_GAME_RET_NONE; } contentInfo = dir; usrdir = dir + "/USRDIR"; path_set = true; } return CELL_GAME_RET_OK; }
void printf(ARMv7Thread& context, vm::cptr<char> fmt, armv7_va_args_t va_args) { sceLibc.Warning("printf(fmt=*0x%x)", fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sceLibc.Log("*** -> '%s'", result); LOG_NOTICE(TTY, result); }
s32 send(s32 s, vm::cptr<char> buf, u32 len, s32 flags) { libnet.warning("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags); s = g_socketMap[s]; s32 ret = ::send(s, buf.get_ptr(), len, flags); get_errno() = getLastError(); return ret; }
s32 setsockopt(s32 s, s32 level, s32 optname, vm::cptr<char> optval, u32 optlen) { libnet.warning("socket(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen); s = g_socketMap[s]; s32 ret = ::setsockopt(s, level, optname, optval.get_ptr(), optlen); get_errno() = getLastError(); return ret; }
s32 sys_fs_get_block_size(vm::cptr<char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size, vm::ptr<u64> arg4) { sys_fs.Todo("sys_fs_get_block_size(path=*0x%x, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", path, sector_size, block_size, arg4); sys_fs.Todo("*** path = '%s'", path.get_ptr()); *sector_size = 4096; // ? *block_size = 4096; // ? return CELL_OK; }
s32 sys_fs_truncate(vm::cptr<char> path, u64 size) { sys_fs.Warning("sys_fs_truncate(path=*0x%x, size=0x%llx)", path, size); sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string ps3_path = path.get_ptr(); if (!Emu.GetVFS().ExistsFile(ps3_path)) { return CELL_FS_ENOENT; } if (!Emu.GetVFS().TruncateFile(ps3_path, size)) { return CELL_FS_EIO; // ??? } return CELL_OK; }
s32 cellFsAioInit(vm::cptr<char> mount_point) { cellFs.warning("cellFsAioInit(mount_point=*0x%x)", mount_point); cellFs.warning("*** mount_point = '%s'", mount_point.get_ptr()); // TODO: create AIO thread (if not exists) for specified mount point fxm::get_always<fs_aio_manager>(); return CELL_OK; }
void printf(ARMv7Thread& context, vm::cptr<char> fmt, armv7_va_args_t va_args) { sceLibc.warning("printf(fmt=*0x%x)", fmt); sceLibc.trace("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sceLibc.trace("*** -> '%s'", result); _log::g_tty_file.log(result); }
void sprintf(ARMv7Thread& context, vm::ptr<char> str, vm::cptr<char> fmt, armv7_va_args_t va_args) { sceLibc.warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt); sceLibc.trace("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sceLibc.trace("*** -> '%s'", result); ::memcpy(str.get_ptr(), result.c_str(), result.size() + 1); }
s32 sys_fs_unlink(vm::cptr<char> path) { sys_fs.Warning("sys_fs_unlink(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string ps3_path = path.get_ptr(); if (!Emu.GetVFS().ExistsFile(ps3_path)) { return CELL_FS_ENOENT; } if (!Emu.GetVFS().RemoveFile(ps3_path)) { return CELL_FS_EIO; // ??? } sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr()); return CELL_OK; }
s32 sys_fs_rmdir(vm::cptr<char> path) { sys_fs.Warning("sys_fs_rmdir(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string ps3_path = path.get_ptr(); if (!Emu.GetVFS().ExistsDir(ps3_path)) { return CELL_FS_ENOENT; } if (!Emu.GetVFS().RemoveDir(ps3_path)) { return CELL_FS_EIO; // ??? } sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr()); return CELL_OK; }
s32 sceKernelCreateCond(vm::cptr<char> pName, u32 attr, s32 mutexId, vm::cptr<SceKernelCondOptParam> pOptParam) { sceLibKernel.Error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam); if (s32 id = g_psv_cond_list.create(pName.get_ptr(), attr, mutexId)) { return id; } return SCE_KERNEL_ERROR_ERROR; }
vm::ptr<char> _sys_strcpy(vm::ptr<char> dest, vm::cptr<char> source) { sysPrxForUser.trace("_sys_strcpy(dest=*0x%x, source=*0x%x)", dest, source); if (strcpy(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) { throw EXCEPTION("Unexpected strcpy() result"); } return dest; }
s32 sceKernelCreateEventFlag(vm::cptr<char> pName, u32 attr, u32 initPattern, vm::cptr<SceKernelEventFlagOptParam> pOptParam) { sceLibKernel.Error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam); if (s32 id = g_psv_ef_list.create(pName.get_ptr(), attr, initPattern)) { return id; } return SCE_KERNEL_ERROR_ERROR; }
s32 sceKernelCreateMutex(vm::cptr<char> pName, u32 attr, s32 initCount, vm::cptr<SceKernelMutexOptParam> pOptParam) { sceLibKernel.Error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam); if (s32 id = g_psv_mutex_list.create(pName.get_ptr(), attr, initCount)) { return id; } return SCE_KERNEL_ERROR_ERROR; }
s32 cellFsGetFreeSize(vm::cptr<char> path, vm::ptr<u32> block_size, vm::ptr<u64> block_count) { cellFs.Warning("cellFsGetFreeSize(path=*0x%x, block_size=*0x%x, block_count=*0x%x)", path, block_size, block_count); cellFs.Warning("*** path = '%s'", path.get_ptr()); // TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks *block_size = 4096; // ? *block_count = 10 * 1024 * 1024; // ? return CELL_OK; }
s32 sys_fs_mkdir(vm::cptr<char> path, s32 mode) { sys_fs.Warning("sys_fs_mkdir(path=*0x%x, mode=%#o)", path, mode); sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string ps3_path = path.get_ptr(); if (Emu.GetVFS().ExistsDir(ps3_path)) { return CELL_FS_EEXIST; } if (!Emu.GetVFS().CreatePath(ps3_path)) { return CELL_FS_EIO; // ??? } sys_fs.Notice("sys_fs_mkdir(): directory '%s' created", path.get_ptr()); return CELL_OK; }
s32 sendto(s32 s, vm::cptr<char> buf, u32 len, s32 flags, vm::ptr<sys_net_sockaddr> addr, u32 addrlen) { sys_net.Warning("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen); sockaddr _addr; memcpy(&_addr, addr.get_ptr(), sizeof(sockaddr)); _addr.sa_family = addr->sa_family; int ret = ::sendto(s, buf.get_ptr(), len, flags, &_addr, addrlen); *g_lastError = getLastError(); return ret; }
s32 cellGameThemeInstall(vm::cptr<char> usrdirPath, vm::cptr<char> fileName, u32 option) { cellGame.todo("cellGameThemeInstall(usrdirPath=%s, fileName=%s, option=0x%x)", usrdirPath, fileName, option); if (!fileName || !usrdirPath || usrdirPath.size() > CELL_GAME_PATH_MAX) { return CELL_GAME_ERROR_PARAM; } return CELL_OK; }
vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::cptr<char> source, u32 len) { sysPrxForUser.trace("_sys_strncat(dest=*0x%x, source=*0x%x, len=%d)", dest, source, len); if (strncat(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) { throw EXCEPTION("Unexpected strncat() result"); } return dest; }
error_code sys_fs_opendir(vm::cptr<char> path, vm::ptr<u32> fd) { sys_fs.warning("sys_fs_opendir(path=%s, fd=*0x%x)", path, fd); const std::string& local_path = vfs::get(path.get_ptr()); if (local_path.empty()) { sys_fs.error("sys_fs_opendir(%s) failed: device not mounted", path); return CELL_ENOTMOUNTED; } // TODO: other checks for path if (fs::is_file(local_path)) { sys_fs.error("sys_fs_opendir(%s) failed: path is a file", path); return CELL_ENOTDIR; } fs::dir dir(local_path); if (!dir) { sys_fs.error("sys_fs_opendir(%s): failed to open directory", path); return CELL_ENOENT; } const auto _dir = idm::make_ptr<lv2_dir>(path.get_ptr(), std::move(dir)); if (!_dir) { // out of file descriptors return CELL_EMFILE; } *fd = _dir->id; sys_fs.notice("sys_fs_opendir(%s) -> lv2_fs_id %d", path, _dir->id); return CELL_OK; }
s32 cellSailPlayerCreateDescriptor(vm::ptr<CellSailPlayer> pSelf, s32 streamType, vm::ptr<void> pMediaInfo, vm::cptr<char> pUri, vm::pptr<CellSailDescriptor> ppDesc) { cellSail.todo("cellSailPlayerCreateDescriptor(pSelf=*0x%x, streamType=%d, pMediaInfo=*0x%x, pUri=*0x%x, ppDesc=**0x%x)", pSelf, streamType, pMediaInfo, pUri, ppDesc); u32 descriptorAddress = vm::alloc(sizeof(CellSailDescriptor), vm::main); auto descriptor = vm::ptr<CellSailDescriptor>::make(descriptorAddress); *ppDesc = descriptor; descriptor->streamType = streamType; descriptor->registered = false; //pSelf->descriptors = 0; pSelf->repeatMode = 0; switch (streamType) { case CELL_SAIL_STREAM_PAMF: { std::string uri = pUri.get_ptr(); if (uri.substr(0, 12) == "x-cell-fs://") { std::string path = uri.substr(12); vfsFile f; if (f.Open(path)) { u64 size = f.GetSize(); u32 buffer = vm::alloc(size, vm::main); auto bufPtr = vm::cptr<PamfHeader>::make(buffer); PamfHeader *buf = const_cast<PamfHeader*>(bufPtr.get_ptr()); assert(f.Read(buf, size) == size); u32 sp_ = vm::alloc(sizeof(CellPamfReader), vm::main); auto sp = vm::ptr<CellPamfReader>::make(sp_); u32 reader = cellPamfReaderInitialize(sp, bufPtr, size, 0); descriptor->buffer = buffer; descriptor->sp_ = sp_; } else { cellSail.warning("Couldn't open PAMF: %s", uri.c_str()); } } else { cellSail.warning("Unhandled uri: %s", uri.c_str()); } break; } default: cellSail.error("Unhandled stream type: %d", streamType); } return CELL_OK; }