jak-project/game/sce/sif_ee.cpp

184 lines
3.9 KiB
C++
Raw Normal View History

#include "sif_ee.h"
#include <cstdio>
#include <cstring>
#include <unordered_map>
#include "common/util/Assert.h"
#include "common/util/FileUtil.h"
2020-08-22 22:30:12 -04:00
#include "game/runtime.h"
#include "game/system/iop_thread.h"
2020-08-22 22:30:12 -04:00
namespace ee {
2020-08-26 01:21:33 -04:00
namespace {
2020-08-22 22:30:12 -04:00
::IOP* iop;
std::unordered_map<s32, FILE*> sce_fds;
} // namespace
2020-08-22 22:30:12 -04:00
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();
2020-08-22 22:30:12 -04:00
}
void sceSifInitRpc(unsigned int mode) {
(void)mode;
}
int sceSifRebootIop(const char* imgfile) {
(void)imgfile;
return 1;
}
int sceSifSyncIop() {
return 1;
}
2020-08-26 01:21:33 -04:00
void sceFsReset() {}
2020-08-22 22:30:12 -04:00
int sceSifLoadModule(const char* name, int arg_size, const char* args) {
2020-08-26 01:21:33 -04:00
if (!strcmp(name, "cdrom0:\\\\DRIVERS\\\\OVERLORD.IRX;1") ||
!strcmp(name, "host0:binee/overlord.irx") || !strcmp(name, "host0:bin/overlord.irx")) {
2020-08-22 22:30:12 -04:00
const char* src = args;
char* dst = iop->overlord_arg_data;
int cnt;
iop->overlord_argv[0] = nullptr;
2020-08-26 01:21:33 -04:00
for (cnt = 1; src - args < arg_size; cnt++) {
2020-08-22 22:30:12 -04:00
auto len = strlen(src);
memcpy(dst, src, len + 1);
iop->overlord_argv[cnt] = dst;
dst += len + 1;
src += len + 1;
}
iop->overlord_argc = cnt;
2020-08-26 01:21:33 -04:00
for (int i = 0; i < cnt; i++) {
if (iop->overlord_argv[i])
2020-08-22 22:30:12 -04:00
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;
}
2020-08-26 01:21:33 -04:00
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
2020-08-22 22:30:12 -04:00
iop->kernel.sif_rpc(bd->rpcd.id, fno, mode, send, ssize, recv, rsize);
iop->signal_run_iop();
2020-08-22 22:30:12 -04:00
return 0;
}
s32 sceSifCheckStatRpc(sceSifRpcData* bd) {
iop->signal_run_iop();
2020-08-22 22:30:12 -04:00
return iop->kernel.sif_busy(bd->id);
}
s32 sceSifBindRpc(sceSifClientData* bd, u32 request, u32 mode) {
ASSERT(mode == 1); // async
2020-08-22 22:30:12 -04:00
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 = file_util::open_file(name.c_str(), "rb");
} break;
default: {
fp = file_util::open_file(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