Files
jak-project/game/sce/sif_ee.cpp
Tyler Wilding d3cc739e43 jakx: Commit existing work from other PRs (#4112)
This attempts to get into master whatever work was done in this PR /
it's earlier PR https://github.com/open-goal/jak-project/pull/3965

I don't want this work to be lost / floating around in massive PRs.

However the changes are:
- switch to ntsc_v1 instead of PAL as the development target, as we have
done for all other games
- remove most of the copied-from-jak2/3 changes as they need to be
confirmed during the decompilation process not just assumed
- avoids committing any changes to `game/kernel/common` as it was not
clear to me if these were changes made in jak x's kernel that were not
properly broken out into it's own functions. We don't want to
accidentally introduce bugs into jak1-3's kernel code.
- in other words, if the change in the kernel only happens in jak x...it
should likely be specific to jak x's kernel, not common.

---------

Co-authored-by: VodBox <dillon@vodbox.io>
Co-authored-by: yodah <greenboyyodah@gmail.com>
2025-12-31 21:08:44 -05:00

194 lines
4.2 KiB
C++

#include "sif_ee.h"
#include <cstdio>
#include <cstring>
#include <unordered_map>
#include "common/util/Assert.h"
#include "common/util/FileUtil.h"
#include "game/runtime.h"
#include "game/system/iop_thread.h"
namespace ee {
namespace {
::IOP* iop;
std::unordered_map<s32, FILE*> 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") || !strcmp(name, "host0:bin/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();
return 0;
}
s32 sceSifCheckStatRpc(sceSifRpcData* bd) {
iop->signal_run_iop();
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 = file_util::open_file(name.c_str(), "rb");
} break;
default: {
// either append or truncate
file_util::create_dir_if_needed_for_file(name);
if (flag & SCE_TRUNC) {
fp = file_util::open_file(name.c_str(), "w");
} else {
fp = file_util::open_file(name.c_str(), "a+");
}
} 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 sceMkDir(const char* filename, s32 flag) {
return -1;
}
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