#include #include #include #include "common/util/FileUtil.h" #include "sif_ee.h" #include "game/system/iop_thread.h" #include "game/runtime.h" #include "common/util/Assert.h" namespace ee { namespace { ::IOP* iop; std::unordered_map sce_fds; } // namespace void LIBRARY_sceSif_register(::IOP* i) { iop = i; } void LIBRARY_INIT_sceSif() { iop = nullptr; for (auto& kv : sce_fds) { fclose(kv.second); } sce_fds.clear(); } void sceSifInitRpc(unsigned int mode) { (void)mode; } int sceSifRebootIop(const char* imgfile) { (void)imgfile; return 1; } int sceSifSyncIop() { return 1; } void sceFsReset() {} int sceSifLoadModule(const char* name, int arg_size, const char* args) { if (!strcmp(name, "cdrom0:\\\\DRIVERS\\\\OVERLORD.IRX;1") || !strcmp(name, "host0:binee/overlord.irx")) { const char* src = args; char* dst = iop->overlord_arg_data; int cnt; iop->overlord_argv[0] = nullptr; for (cnt = 1; src - args < arg_size; cnt++) { auto len = strlen(src); memcpy(dst, src, len + 1); iop->overlord_argv[cnt] = dst; dst += len + 1; src += len + 1; } iop->overlord_argc = cnt; for (int i = 0; i < cnt; i++) { if (iop->overlord_argv[i]) printf("arg %d : %s\n", i, iop->overlord_argv[i]); } iop->set_ee_main_mem(g_ee_main_mem); iop->send_status(IOP_Status::IOP_OVERLORD_INIT); iop->wait_for_overlord_init_finish(); } return 1; } s32 sceSifCallRpc(sceSifClientData* bd, u32 fno, u32 mode, void* send, s32 ssize, void* recv, s32 rsize, void* end_func, void* end_para) { ASSERT(!end_func); ASSERT(!end_para); ASSERT(mode == 1); // async iop->kernel.sif_rpc(bd->rpcd.id, fno, mode, send, ssize, recv, rsize); iop->signal_run_iop(false); return 0; } s32 sceSifCheckStatRpc(sceSifRpcData* bd) { iop->signal_run_iop(false); return iop->kernel.sif_busy(bd->id); } s32 sceSifBindRpc(sceSifClientData* bd, u32 request, u32 mode) { ASSERT(mode == 1); // async bd->rpcd.id = request; bd->serve = (sceSifServeData*)1; return 0; } s32 sceOpen(const char* filename, s32 flag) { FILE* fp = nullptr; auto name = file_util::get_file_path({filename}); switch (flag) { case SCE_RDONLY: { fp = fopen(name.c_str(), "rb"); } break; default: { fp = fopen(name.c_str(), "w"); } break; } if (!fp) { printf("[SCE] sceOpen(%s) failed.\n", name.c_str()); return -1; } s32 fp_idx = sce_fds.size() + 1; sce_fds[fp_idx] = fp; return fp_idx; } s32 sceClose(s32 fd) { if (fd < 0) { // todo, what should we really return? return 0; } auto kv = sce_fds.find(fd); if (kv != sce_fds.end()) { fclose(kv->second); sce_fds.erase(fd); return 0; } else { printf("[SCE] sceClose called on invalid fd\n"); return 0; } } s32 sceRead(s32 fd, void* buf, s32 nbyte) { auto kv = sce_fds.find(fd); if (kv == sce_fds.end()) { return -1; } else { return fread(buf, 1, nbyte, kv->second); } } s32 sceWrite(s32 fd, const void* buf, s32 nbyte) { auto kv = sce_fds.find(fd); if (kv == sce_fds.end()) { ASSERT(false); return -1; } else { return fwrite(buf, 1, nbyte, kv->second); } } s32 sceLseek(s32 fd, s32 offset, s32 where) { auto kv = sce_fds.find(fd); if (kv == sce_fds.end()) { return -1; } else { switch (where) { case SCE_SEEK_CUR: fseek(kv->second, offset, SEEK_CUR); return ftell(kv->second); case SCE_SEEK_END: fseek(kv->second, offset, SEEK_END); return ftell(kv->second); case SCE_SEEK_SET: fseek(kv->second, offset, SEEK_SET); return ftell(kv->second); default: ASSERT(false); return -1; } } } } // namespace ee