queue load single messages

This commit is contained in:
Ziemas 2024-05-12 19:58:31 +02:00
parent 6628fc3600
commit d114ca8309
5 changed files with 208 additions and 13 deletions

View file

@ -3,9 +3,9 @@
#include <cstring>
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "game/common/dgo_rpc_types.h"
#include "game/overlord/common/isocommon.h"
#include "game/overlord/jak3/basefilesystem.h"
#include "game/overlord/jak3/iso_api.h"
#include "game/overlord/jak3/iso_fake.h"
@ -34,7 +34,11 @@ static int s_nDGOMbx;
static u32 DGOThread();
u32 ISOThread();
int NullCallback(ISO_Msg* msg);
int NullCallback(ISO_Hdr* msg);
int CopyDataToEE(ISO_Hdr*);
int CopyDataToIOP(ISO_Hdr*);
int CopyDataTo989snd(ISO_Hdr*);
int CopyData(ISO_LoadSingle*, int);
/* COMPLETE */
void InitDriver() {
@ -158,14 +162,78 @@ u32 ISOThread() {
msg->file = nullptr;
msg->callback = NullCallback;
/* LoadSingle messages */
if (msg->msg_kind >= LOAD_TO_EE_CMD_ID && msg->msg_kind <= LOAD_TO_989SND) {
auto* ls = static_cast<ISO_LoadSingle*>(msg);
int pri = 0;
if (ls->unk40 == 2) {
pri = 2;
}
if (ls->unk40 == 10) {
pri = 4;
}
if (!QueueMessage(msg, pri)) {
break;
}
msg->file = nullptr;
if (msg->msg_kind == LOAD_TO_EE_OFFSET_CMD_ID) {
msg->file = g_pFileSystem->Open(ls->fd, ls->offset, EFileComp::MODE1);
} else if (msg->msg_kind == LOAD_TO_989SND) {
char name[16] = {0};
if (ls->filename) {
strncpy(name, ls->filename, 12);
name[8] = 0;
strcat(name, ".sbk");
auto fd = g_pFileSystem->Find(name);
if (fd) {
msg->file = g_pFileSystem->Open(ls->fd, -1, EFileComp::MODE1);
}
}
} else {
msg->file = g_pFileSystem->Open(ls->fd, -1, EFileComp::MODE1);
}
if (!msg->file) {
msg->m_nStatus = 8;
UnqueueMessage(msg);
ReturnMessage(msg);
break;
}
ls->unk44 = ls->address;
ls->unk48 = 0;
ls->length_to_copy = g_pFileSystem->GetLength(ls->fd);
if (msg->msg_kind == LOAD_TO_989SND) {
ls->length = ls->length_to_copy;
} else {
if (!ls->length_to_copy || ls->length < ls->length_to_copy) {
ls->length_to_copy = ls->length;
}
}
switch (msg->msg_kind) {
case LOAD_TO_EE_CMD_ID:
msg->callback = CopyDataToEE;
break;
case LOAD_TO_IOP_CMD_ID:
msg->callback = CopyDataToIOP;
break;
case LOAD_TO_EE_OFFSET_CMD_ID:
msg->callback = CopyDataToEE;
break;
case LOAD_TO_989SND:
msg->callback = CopyDataTo989snd;
break;
default:
lg::error("unhandled iso msg type {:x}", msg->msg_kind);
break;
ASSERT_NOT_REACHED();
}
msg->m_nStatus = 2;
msg->SetActive(true);
} else if (msg->msg_kind == 0xADEADBEE) {
ReturnMessage(msg);
ExitThread();
}
}
@ -221,13 +289,19 @@ static void ISO_LoadDGO(RPC_Dgo_Cmd* msg) {
return;
}
ASSERT_NOT_REACHED();
msg->buffer1 = msg->buffer_heap_top;
msg->result = 0;
}
static void ISO_LoadNextDGO(RPC_Dgo_Cmd* msg) {}
static void ISO_LoadNextDGO(RPC_Dgo_Cmd* msg) {
ASSERT_NOT_REACHED();
}
static void ISO_CancelDGO(RPC_Dgo_Cmd* msg) {}
static void ISO_CancelDGO(RPC_Dgo_Cmd* msg) {
ASSERT_NOT_REACHED();
}
/* COMPLETE */
const ISOFileDef* FindISOFile(char* name) {
@ -239,7 +313,24 @@ s32 GetISOFileLength(const ISOFileDef* fd) {
return g_pFileSystem->GetLength(fd);
}
int NullCallback(ISO_Msg* msg) {
int CopyDataToEE(ISO_Hdr* msg) {
return CopyData((ISO_LoadSingle*)msg, 0);
}
int CopyDataToIOP(ISO_Hdr* msg) {
return CopyData((ISO_LoadSingle*)msg, 1);
}
int CopyDataTo989snd(ISO_Hdr* msg) {
return CopyData((ISO_LoadSingle*)msg, 2);
}
int CopyData(ISO_LoadSingle*, int) {
ASSERT_NOT_REACHED();
return 0;
}
int NullCallback(ISO_Hdr* msg) {
return 7;
}

View file

@ -4,6 +4,15 @@
#include "game/sce/iop.h"
namespace jak3 {
constexpr int LOAD_TO_EE_CMD_ID = 0x100; // command to load file to ee
constexpr int LOAD_TO_IOP_CMD_ID = 0x101; // command to load to iop
constexpr int LOAD_TO_EE_OFFSET_CMD_ID = 0x102; // command to load file to ee with offset.
constexpr int LOAD_TO_989SND = 0x103;
constexpr int PAUSE_VAG_STREAM = 0x403; // Command to pause a vag stream
constexpr int CONTINUE_VAG_STREAM = 0x404; // Command to continue a vag stream
constexpr int SET_DIALOG_VOLUME = 0x406; // Command to set the volume of vag playback
extern int g_nISOMbx;
struct ISO_Hdr {
@ -22,8 +31,9 @@ struct ISO_Msg : ISO_Hdr {
u32 msg_kind;
int mbx_to_reply;
int thread_id;
int (*callback)(ISO_Msg*);
int (*callback)(ISO_Hdr*);
CBaseFile* file;
u32 priority;
};
struct ISO_LoadDGO : ISO_Msg {
@ -36,6 +46,11 @@ struct ISO_LoadSingle : ISO_Msg {
u32 length;
u32 length_to_copy;
u32 offset;
char* filename;
u32 unk40;
void* unk44;
u32 unk48;
u32 unk4c;
};
int InitISOFS(const char* fs_mode, const char* loading_sceeen);

View file

@ -1,6 +1,10 @@
#include "iso_queue.h"
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "game/overlord/jak3/pagemanager.h"
#include "game/overlord/jak3/util.h"
#include "game/sce/iop.h"
namespace jak3 {
@ -13,6 +17,8 @@ u32 g_auTrapSRAM[N_VAG_CMDS];
int g_nPriQueueSema;
int g_nISOSema;
PriStackEntry gPriStack[N_PRIORITIES];
CPageManager g_PageManager;
void InitBuffers() {
@ -32,4 +38,41 @@ void InitBuffers() {
semap.option = 0;
g_nISOSema = CreateSema(&semap);
}
bool QueueMessage(ISO_Msg* msg, int priority) {
msg->m_nStatus = 2;
msg->priority = priority;
int level = priority == 5;
{
ScopedLock l(g_nPriQueueSema);
if (gPriStack[level].count != 8) {
gPriStack[level].entries[gPriStack[level].count] = msg;
gPriStack[level].count++;
return true;
}
}
msg->m_nStatus = 4;
ReturnMessage(msg);
return false;
}
void UnqueueMessage(ISO_Msg* msg) {}
void ReturnMessage(ISO_Msg* msg) {
if (msg->mbx_to_reply) {
SendMbx(msg->mbx_to_reply, msg);
} else if (msg->thread_id) {
WakeupThread(msg->thread_id);
} else {
// FreeVAGCommand(msg);
ASSERT_NOT_REACHED_MSG("unimplemented");
}
}
} // namespace jak3

View file

@ -1,8 +1,21 @@
#ifndef ISO_QUEUE_H_
#define ISO_QUEUE_H_
#include "game/overlord/jak3/iso.h"
namespace jak3 {
constexpr int N_PRIORITIES = 2;
constexpr int PRI_STACK_LENGTH = 8;
struct PriStackEntry {
ISO_Msg* entries[PRI_STACK_LENGTH];
int count;
};
void InitBuffers();
}
bool QueueMessage(ISO_Msg* msg, int priority);
void ReturnMessage(ISO_Msg* msg);
void UnqueueMessage(ISO_Msg* msg);
} // namespace jak3
#endif // ISO_QUEUE_H_

View file

@ -155,4 +155,37 @@ int CPageManager::TryFreePages(int nPages) {
return 0;
}
CPageManager::CPageList* CPageManager::AllocPageList(int nPages, char unk) {
CPageList* pList = nullptr;
CPage* apCollectedPages[29];
int nPageCount;
if (nPages <= 0) {
return nullptr;
}
if (m_Cache.m_nNumFree < nPages) {
if (nPages >= 29) {
return nullptr;
}
int nFreed = TryFreePages(nPages);
if (nFreed < nPages) {
return nullptr;
}
}
int nPageListID = std::countr_one(m_Cache.m_uAllocatedListMap);
if (nPages >= 29) {
return nullptr;
}
m_Cache.m_uAllocatedListMap |= 1u << nPageListID;
nPageCount = 0;
while (nPageCount < nPages) {
int nPageID = std::countr_one(m_Cache.m_uAllocatedPageMap);
}
}
} // namespace jak3