From 413e214d2c48f4c404a6767e8f70ef519f2bd087 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Wed, 24 Jan 2024 20:01:51 +0100 Subject: [PATCH 01/14] overlrd2: start --- game/CMakeLists.txt | 5 ++ game/overlord/jak3/basefile.h | 21 ++++++++ game/overlord/jak3/basefilesystem.h | 20 ++++++++ game/overlord/jak3/iso_structs.h | 37 ++++++++++++++ game/overlord/jak3/overlord.cpp | 30 +++++++++++ game/overlord/jak3/overlord.h | 18 +++++++ game/overlord/jak3/pagemanager.h | 44 +++++++++++++++++ game/overlord/jak3/ramdisk.cpp | 0 game/overlord/jak3/sbank.cpp | 49 ++++++++++++++++++ game/overlord/jak3/sbank.h | 22 +++++++++ game/overlord/jak3/ssound.cpp | 5 ++ game/overlord/jak3/start.cpp | 71 +++++++++++++++++++++++++++ game/overlord/jak3/vblank_handler.cpp | 9 ++++ 13 files changed, 331 insertions(+) create mode 100644 game/overlord/jak3/basefile.h create mode 100644 game/overlord/jak3/basefilesystem.h create mode 100644 game/overlord/jak3/iso_structs.h create mode 100644 game/overlord/jak3/overlord.cpp create mode 100644 game/overlord/jak3/overlord.h create mode 100644 game/overlord/jak3/pagemanager.h create mode 100644 game/overlord/jak3/ramdisk.cpp create mode 100644 game/overlord/jak3/sbank.cpp create mode 100644 game/overlord/jak3/sbank.h create mode 100644 game/overlord/jak3/ssound.cpp create mode 100644 game/overlord/jak3/start.cpp create mode 100644 game/overlord/jak3/vblank_handler.cpp diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 9359212c431..4e2997a7188 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -251,6 +251,11 @@ set(RUNTIME_SOURCE overlord/jak2/streamlfo.cpp overlord/jak2/streamlist.cpp overlord/jak2/vag.cpp + overlord/jak3/start.cpp + overlord/jak3/overlord.cpp + overlord/jak3/sbank.cpp + overlord/jak3/ssound.cpp + overlord/jak3/vblank_handler.cpp runtime.cpp sce/deci2.cpp sce/iop.cpp diff --git a/game/overlord/jak3/basefile.h b/game/overlord/jak3/basefile.h new file mode 100644 index 00000000000..6d6a2fe6c34 --- /dev/null +++ b/game/overlord/jak3/basefile.h @@ -0,0 +1,21 @@ +#ifndef BASEFILE_H_ +#define BASEFILE_H_ + +#include "game/overlord/jak3/iso_structs.h" +#include "game/overlord/jak3/overlord.h" + +namespace jak3 { +class CBaseFile { + public: + CBaseFile(const ISOFileDef*); + virtual EIsoStatus BeginRead(ISOBuffer*) = 0; + virtual EIsoStatus SyncRead() = 0; + virtual void Close() = 0; + + /* unk return values */ + virtual void Unk1() = 0; + virtual void Unk2() = 0; +}; +} // namespace jak3 + +#endif // BASEFILE_H_ diff --git a/game/overlord/jak3/basefilesystem.h b/game/overlord/jak3/basefilesystem.h new file mode 100644 index 00000000000..2803428231f --- /dev/null +++ b/game/overlord/jak3/basefilesystem.h @@ -0,0 +1,20 @@ +#ifndef BASEFILESYSTEM_H_ +#define BASEFILESYSTEM_H_ + +#include "game/overlord/jak3/iso_structs.h" + +namespace jak3 { +class CBaseFileSystem { + public: + virtual void Init() = 0; + virtual void PollDrive() = 0; + virtual const ISOFileDef* Find(const char* name) = 0; + virtual const ISOFileDef* FindIN(const char* name) = 0; + virtual int GetLength(const ISOFileDef* def) = 0; + virtual int Open(const ISOFileDef* def, int offset, EFileComp mode) = 0; + virtual int OpenWad(const ISOFileDef* def, int offset) = 0; + virtual VagDirEntryJak3* FindVagFile(const char* name) = 0; +}; +} // namespace jak3 + +#endif // BASEFILESYSTEM_H_ diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h new file mode 100644 index 00000000000..7af569aa763 --- /dev/null +++ b/game/overlord/jak3/iso_structs.h @@ -0,0 +1,37 @@ +#ifndef ISO_STRUCTS_H_ +#define ISO_STRUCTS_H_ + +#include "common/common_types.h" + +namespace jak3 { +/* TODO check values */ +enum class EFileComp { MODE0, MODE1, KNOWN_NOT_BLZO }; + +struct VagDirEntryJak3 { + union { + u64 data; + struct { + u64 name : 42; + bool stereo : 1; + bool international : 1; + u8 param : 4; + u64 offset : 16; + }; + }; +}; + +struct VagDirJak3 { + u32 id[2]; + u32 version; + u32 count; + VagDirEntryJak3 entries[0]; +} dir; + +struct VagDirEntry {}; + +struct ISOBuffer {}; + +struct ISOFileDef {}; +} // namespace jak3 + +#endif // ISO_STRUCTS_H_ diff --git a/game/overlord/jak3/overlord.cpp b/game/overlord/jak3/overlord.cpp new file mode 100644 index 00000000000..2e93b9d0a02 --- /dev/null +++ b/game/overlord/jak3/overlord.cpp @@ -0,0 +1,30 @@ +#include "overlord.h" + +#include +#include +#include + +namespace jak3 { +extern int start_overlord(int, const char* const*); + +void Panic() { + printf( + "IOP: *** Overlord panic at 0x%08lx (rel. address 0x%08lx)\n" + "IOP: *** Check mapfile to determine function name.\n" + "IOP: *** Thread halted.\n", + (intptr_t)__builtin_return_address(0), + (intptr_t)__builtin_return_address(0) - (intptr_t)start_overlord); + while (true) + ; +} + +char* strncpyz(char* dst, const char* src, size_t sz) { + if (sz) { + strncpy(dst, src, sz); + dst[sz - 1] = '\0'; + } + + return dst; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/overlord.h b/game/overlord/jak3/overlord.h new file mode 100644 index 00000000000..8fae9fe51f2 --- /dev/null +++ b/game/overlord/jak3/overlord.h @@ -0,0 +1,18 @@ +#ifndef OVERLORD_H_ +#define OVERLORD_H_ + +#include + +namespace jak3 { +enum class EIsoStatus { Unk }; + +int start_overlord_wrapper(int argc, const char* const* argv, bool* signal); +void Panic(); +char* strncpyz(char* dst, const char* src, size_t sz); + +void InitSound(); + +int VBlank_Initialize(); +} // namespace jak3 + +#endif diff --git a/game/overlord/jak3/pagemanager.h b/game/overlord/jak3/pagemanager.h new file mode 100644 index 00000000000..6c5e5283d1b --- /dev/null +++ b/game/overlord/jak3/pagemanager.h @@ -0,0 +1,44 @@ +#ifndef PAGEMANAGER_H_ +#define PAGEMANAGER_H_ + +#include "common/common_types.h" + +namespace jak3 { +class CPageManager { + public: + class CPage { + public: + CPage(u8*, u8*, int); + int AddRef(); + int ReleaseRef(); + int AddDmaRef(); + int ReleaseDmaRef(); + void FromPagesCopy(u8* pInPageData, u8* pDest, int nNumBytes); + }; + + class CPageList { + int AddActivePages(int); + int CancelActivePages(); + CPage* StepActivePage(); + void GarbageCollect(); + }; + + void Initialize(); + CPageList* AllocPageListBytes(int nBytes, char unk); + CPageList* AllocPageList(int nPages, char unk); + CPageList* GrowPageList(CPageList* list, char nPages); + int FreePageList(CPageList* list); + int Unk(int nUnk); + void GarbageCollect(); + + private: + class CCache { + public: + int Initialize(); + }; + CCache m_Cache; +}; + +} // namespace jak3 + +#endif // PAGEMANAGER_H_ diff --git a/game/overlord/jak3/ramdisk.cpp b/game/overlord/jak3/ramdisk.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/game/overlord/jak3/sbank.cpp b/game/overlord/jak3/sbank.cpp new file mode 100644 index 00000000000..170b71820f1 --- /dev/null +++ b/game/overlord/jak3/sbank.cpp @@ -0,0 +1,49 @@ +#include "sbank.h" + +#include "overlord.h" + +namespace jak3 { + +SoundBankInfo gCommonBank, gModeBank; +SoundBankInfo gLevelBanks[6]; + +SoundBankInfo* gBanks[8] = { + &gCommonBank, &gModeBank, &gLevelBanks[0], &gLevelBanks[1], + &gLevelBanks[2], &gLevelBanks[3], &gLevelBanks[4], &gLevelBanks[5], +}; + +void InitBanks() { + for (int i = 0; i < 8; i++) { + gBanks[i]->in_use = false; + gBanks[i]->unk = 0; + gBanks[i]->unk2 = 0; + gBanks[i]->index = i; + } + + strncpyz(gBanks[0]->slot_name, "common", 16); + gBanks[0]->spu_size = 0xbbe40; + gBanks[0]->spu_loc = 0x1d1c0; + strncpyz(gBanks[1]->slot_name, "mode", 16); + gBanks[1]->spu_size = 0x25400; + gBanks[1]->spu_loc = 0xe0000; + strncpyz(gBanks[2]->slot_name, "level0", 16); + gBanks[2]->spu_size = 0x51400; + gBanks[2]->spu_loc = 0x105400; + strncpyz(gBanks[3]->slot_name, "level0h", 16); + gBanks[3]->spu_size = 0x28a00; + gBanks[3]->spu_loc = 0x12de00; + strncpyz(gBanks[4]->slot_name, "level1", 16); + gBanks[4]->spu_size = 0x51400; + gBanks[4]->spu_loc = 0x156800; + strncpyz(gBanks[5]->slot_name, "level1h", 16); + gBanks[5]->spu_size = 0x28a00; + gBanks[5]->spu_loc = 0x17f200; + strncpyz(gBanks[6]->slot_name, "level2", 16); + gBanks[6]->spu_size = 0x51400; + gBanks[6]->spu_loc = 0x1a7c00; + strncpyz(gBanks[7]->slot_name, "level2h", 16); + gBanks[7]->spu_size = 0x28a00; + gBanks[7]->spu_loc = 0x1d0600; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/sbank.h b/game/overlord/jak3/sbank.h new file mode 100644 index 00000000000..310f890ef34 --- /dev/null +++ b/game/overlord/jak3/sbank.h @@ -0,0 +1,22 @@ +#ifndef SBANK_H_ +#define SBANK_H_ + +#include "common/common_types.h" + +namespace jak3 { +struct SoundBankInfo { + char bank_name[16]; + char slot_name[16]; + u32 spu_loc; + u32 spu_size; + u32 unk; + bool in_use; + u8 unk2; + u8 unk3; + u8 index; + u32 unk4; +}; +void InitBanks(); +} // namespace jak3 + +#endif // SBANK_H_ diff --git a/game/overlord/jak3/ssound.cpp b/game/overlord/jak3/ssound.cpp new file mode 100644 index 00000000000..ea3406f4f2e --- /dev/null +++ b/game/overlord/jak3/ssound.cpp @@ -0,0 +1,5 @@ +#include "overlord.h" + +namespace jak3 { +void InitSound() {} +} // namespace jak3 diff --git a/game/overlord/jak3/start.cpp b/game/overlord/jak3/start.cpp new file mode 100644 index 00000000000..f53da86a3e8 --- /dev/null +++ b/game/overlord/jak3/start.cpp @@ -0,0 +1,71 @@ +#include +#include + +#include "overlord.h" +#include "sbank.h" + +#include "game/sce/iop.h" + +namespace jak3 { +using namespace iop; + +int start_overlord(int argc, const char* const* argp) { + ThreadParam thp; + + if (argc < 0) { + Panic(); + } + + if (sceSifCheckInit() == 0) { + sceSifInit(); + } + sceSifInitRpc(0); + printf("======== overlrd2.irx startup ========\n"); + // printf(" mem size: %lu\n", QueryMemSize()); + // printf("total mem free: %lu\n", QueryTotalFreeMemSize()); + // printf(" max mem free: %lu\n", QueryMaxFreeMemSize()); + // printf(" used: %lu\n", QueryMemSize() - QueryTotalFreeMemSize()); + // printf(" start() addr: 0x%08x\n", start_overlord); + //__do_global_ctors(); + InitBanks(); + InitSound(); + VBlank_Initialize(); + + return 0; +} + +static s32 gargc; +static const char* const* gargv; +static bool* init_complete; + +static u32 call_start() { + start_overlord(gargc, gargv); + *init_complete = true; + + while (true) { + SleepThread(); + } + return 0; +} + +int start_overlord_wrapper(int argc, const char* const* argv, bool* signal) { + ThreadParam param = {}; + + gargc = argc; + gargv = argv; + init_complete = signal; + + param.attr = TH_C; + param.initPriority = 0; + param.stackSize = 0x800; + param.option = 0; + strcpy(param.name, "start"); // added for debug + param.entry = call_start; + + auto start_thread = CreateThread(¶m); + StartThread(start_thread, 0); + + return 0; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/vblank_handler.cpp b/game/overlord/jak3/vblank_handler.cpp new file mode 100644 index 00000000000..b2f6808b717 --- /dev/null +++ b/game/overlord/jak3/vblank_handler.cpp @@ -0,0 +1,9 @@ +#include "overlord.h" + +namespace jak3 { + +int VBlank_Initialize() { + return 0; +} + +} // namespace jak3 From 8c1948db682b66bda7e8eedf54eb11e4fef19f0b Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 25 Jan 2024 17:54:48 +0100 Subject: [PATCH 02/14] overlrd2: angle lookup table --- game/overlord/jak3/ssound.cpp | 110 ++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/game/overlord/jak3/ssound.cpp b/game/overlord/jak3/ssound.cpp index ea3406f4f2e..497aefc993d 100644 --- a/game/overlord/jak3/ssound.cpp +++ b/game/overlord/jak3/ssound.cpp @@ -1,5 +1,115 @@ #include "overlord.h" +#include "common/common_types.h" + namespace jak3 { + +static s16 angle_table[2056] = { + 180, 0, 180, 0, 90, 90, 270, 270, 180, 0, 180, 0, 90, 90, 270, 270, 180, 0, 180, 0, + 90, 90, 270, 270, 180, 0, 180, 0, 90, 90, 270, 270, 180, 0, 180, 0, 90, 90, 270, 270, + 179, 1, 181, 359, 91, 89, 269, 271, 179, 1, 181, 359, 91, 89, 269, 271, 179, 1, 181, 359, + 91, 89, 269, 271, 179, 1, 181, 359, 91, 89, 269, 271, 178, 2, 182, 358, 92, 88, 268, 272, + 178, 2, 182, 358, 92, 88, 268, 272, 178, 2, 182, 358, 92, 88, 268, 272, 178, 2, 182, 358, + 92, 88, 268, 272, 178, 2, 182, 358, 92, 88, 268, 272, 177, 3, 183, 357, 93, 87, 267, 273, + 177, 3, 183, 357, 93, 87, 267, 273, 177, 3, 183, 357, 93, 87, 267, 273, 177, 3, 183, 357, + 93, 87, 267, 273, 176, 4, 184, 356, 94, 86, 266, 274, 176, 4, 184, 356, 94, 86, 266, 274, + 176, 4, 184, 356, 94, 86, 266, 274, 176, 4, 184, 356, 94, 86, 266, 274, 176, 4, 184, 356, + 94, 86, 266, 274, 175, 5, 185, 355, 95, 85, 265, 275, 175, 5, 185, 355, 95, 85, 265, 275, + 175, 5, 185, 355, 95, 85, 265, 275, 175, 5, 185, 355, 95, 85, 265, 275, 174, 6, 186, 354, + 96, 84, 264, 276, 174, 6, 186, 354, 96, 84, 264, 276, 174, 6, 186, 354, 96, 84, 264, 276, + 174, 6, 186, 354, 96, 84, 264, 276, 174, 6, 186, 354, 96, 84, 264, 276, 173, 7, 187, 353, + 97, 83, 263, 277, 173, 7, 187, 353, 97, 83, 263, 277, 173, 7, 187, 353, 97, 83, 263, 277, + 173, 7, 187, 353, 97, 83, 263, 277, 172, 8, 188, 352, 98, 82, 262, 278, 172, 8, 188, 352, + 98, 82, 262, 278, 172, 8, 188, 352, 98, 82, 262, 278, 172, 8, 188, 352, 98, 82, 262, 278, + 172, 8, 188, 352, 98, 82, 262, 278, 171, 9, 189, 351, 99, 81, 261, 279, 171, 9, 189, 351, + 99, 81, 261, 279, 171, 9, 189, 351, 99, 81, 261, 279, 171, 9, 189, 351, 99, 81, 261, 279, + 171, 9, 189, 351, 99, 81, 261, 279, 170, 10, 190, 350, 100, 80, 260, 280, 170, 10, 190, 350, + 100, 80, 260, 280, 170, 10, 190, 350, 100, 80, 260, 280, 170, 10, 190, 350, 100, 80, 260, 280, + 169, 11, 191, 349, 101, 79, 259, 281, 169, 11, 191, 349, 101, 79, 259, 281, 169, 11, 191, 349, + 101, 79, 259, 281, 169, 11, 191, 349, 101, 79, 259, 281, 169, 11, 191, 349, 101, 79, 259, 281, + 168, 12, 192, 348, 102, 78, 258, 282, 168, 12, 192, 348, 102, 78, 258, 282, 168, 12, 192, 348, + 102, 78, 258, 282, 168, 12, 192, 348, 102, 78, 258, 282, 168, 12, 192, 348, 102, 78, 258, 282, + 167, 13, 193, 347, 103, 77, 257, 283, 167, 13, 193, 347, 103, 77, 257, 283, 167, 13, 193, 347, + 103, 77, 257, 283, 167, 13, 193, 347, 103, 77, 257, 283, 166, 14, 194, 346, 104, 76, 256, 284, + 166, 14, 194, 346, 104, 76, 256, 284, 166, 14, 194, 346, 104, 76, 256, 284, 166, 14, 194, 346, + 104, 76, 256, 284, 166, 14, 194, 346, 104, 76, 256, 284, 165, 15, 195, 345, 105, 75, 255, 285, + 165, 15, 195, 345, 105, 75, 255, 285, 165, 15, 195, 345, 105, 75, 255, 285, 165, 15, 195, 345, + 105, 75, 255, 285, 165, 15, 195, 345, 105, 75, 255, 285, 164, 16, 196, 344, 106, 74, 254, 286, + 164, 16, 196, 344, 106, 74, 254, 286, 164, 16, 196, 344, 106, 74, 254, 286, 164, 16, 196, 344, + 106, 74, 254, 286, 164, 16, 196, 344, 106, 74, 254, 286, 163, 17, 197, 343, 107, 73, 253, 287, + 163, 17, 197, 343, 107, 73, 253, 287, 163, 17, 197, 343, 107, 73, 253, 287, 163, 17, 197, 343, + 107, 73, 253, 287, 163, 17, 197, 343, 107, 73, 253, 287, 162, 18, 198, 342, 108, 72, 252, 288, + 162, 18, 198, 342, 108, 72, 252, 288, 162, 18, 198, 342, 108, 72, 252, 288, 162, 18, 198, 342, + 108, 72, 252, 288, 162, 18, 198, 342, 108, 72, 252, 288, 161, 19, 199, 341, 109, 71, 251, 289, + 161, 19, 199, 341, 109, 71, 251, 289, 161, 19, 199, 341, 109, 71, 251, 289, 161, 19, 199, 341, + 109, 71, 251, 289, 161, 19, 199, 341, 109, 71, 251, 289, 160, 20, 200, 340, 110, 70, 250, 290, + 160, 20, 200, 340, 110, 70, 250, 290, 160, 20, 200, 340, 110, 70, 250, 290, 160, 20, 200, 340, + 110, 70, 250, 290, 160, 20, 200, 340, 110, 70, 250, 290, 159, 21, 201, 339, 111, 69, 249, 291, + 159, 21, 201, 339, 111, 69, 249, 291, 159, 21, 201, 339, 111, 69, 249, 291, 159, 21, 201, 339, + 111, 69, 249, 291, 159, 21, 201, 339, 111, 69, 249, 291, 158, 22, 202, 338, 112, 68, 248, 292, + 158, 22, 202, 338, 112, 68, 248, 292, 158, 22, 202, 338, 112, 68, 248, 292, 158, 22, 202, 338, + 112, 68, 248, 292, 158, 22, 202, 338, 112, 68, 248, 292, 157, 23, 203, 337, 113, 67, 247, 293, + 157, 23, 203, 337, 113, 67, 247, 293, 157, 23, 203, 337, 113, 67, 247, 293, 157, 23, 203, 337, + 113, 67, 247, 293, 157, 23, 203, 337, 113, 67, 247, 293, 157, 23, 203, 337, 113, 67, 247, 293, + 156, 24, 204, 336, 114, 66, 246, 294, 156, 24, 204, 336, 114, 66, 246, 294, 156, 24, 204, 336, + 114, 66, 246, 294, 156, 24, 204, 336, 114, 66, 246, 294, 156, 24, 204, 336, 114, 66, 246, 294, + 155, 25, 205, 335, 115, 65, 245, 295, 155, 25, 205, 335, 115, 65, 245, 295, 155, 25, 205, 335, + 115, 65, 245, 295, 155, 25, 205, 335, 115, 65, 245, 295, 155, 25, 205, 335, 115, 65, 245, 295, + 154, 26, 206, 334, 116, 64, 244, 296, 154, 26, 206, 334, 116, 64, 244, 296, 154, 26, 206, 334, + 116, 64, 244, 296, 154, 26, 206, 334, 116, 64, 244, 296, 154, 26, 206, 334, 116, 64, 244, 296, + 154, 26, 206, 334, 116, 64, 244, 296, 153, 27, 207, 333, 117, 63, 243, 297, 153, 27, 207, 333, + 117, 63, 243, 297, 153, 27, 207, 333, 117, 63, 243, 297, 153, 27, 207, 333, 117, 63, 243, 297, + 153, 27, 207, 333, 117, 63, 243, 297, 153, 27, 207, 333, 117, 63, 243, 297, 152, 28, 208, 332, + 118, 62, 242, 298, 152, 28, 208, 332, 118, 62, 242, 298, 152, 28, 208, 332, 118, 62, 242, 298, + 152, 28, 208, 332, 118, 62, 242, 298, 152, 28, 208, 332, 118, 62, 242, 298, 151, 29, 209, 331, + 119, 61, 241, 299, 151, 29, 209, 331, 119, 61, 241, 299, 151, 29, 209, 331, 119, 61, 241, 299, + 151, 29, 209, 331, 119, 61, 241, 299, 151, 29, 209, 331, 119, 61, 241, 299, 151, 29, 209, 331, + 119, 61, 241, 299, 150, 30, 210, 330, 120, 60, 240, 300, 150, 30, 210, 330, 120, 60, 240, 300, + 150, 30, 210, 330, 120, 60, 240, 300, 150, 30, 210, 330, 120, 60, 240, 300, 150, 30, 210, 330, + 120, 60, 240, 300, 150, 30, 210, 330, 120, 60, 240, 300, 149, 31, 211, 329, 121, 59, 239, 301, + 149, 31, 211, 329, 121, 59, 239, 301, 149, 31, 211, 329, 121, 59, 239, 301, 149, 31, 211, 329, + 121, 59, 239, 301, 149, 31, 211, 329, 121, 59, 239, 301, 149, 31, 211, 329, 121, 59, 239, 301, + 148, 32, 212, 328, 122, 58, 238, 302, 148, 32, 212, 328, 122, 58, 238, 302, 148, 32, 212, 328, + 122, 58, 238, 302, 148, 32, 212, 328, 122, 58, 238, 302, 148, 32, 212, 328, 122, 58, 238, 302, + 148, 32, 212, 328, 122, 58, 238, 302, 148, 32, 212, 328, 122, 58, 238, 302, 147, 33, 213, 327, + 123, 57, 237, 303, 147, 33, 213, 327, 123, 57, 237, 303, 147, 33, 213, 327, 123, 57, 237, 303, + 147, 33, 213, 327, 123, 57, 237, 303, 147, 33, 213, 327, 123, 57, 237, 303, 147, 33, 213, 327, + 123, 57, 237, 303, 146, 34, 214, 326, 124, 56, 236, 304, 146, 34, 214, 326, 124, 56, 236, 304, + 146, 34, 214, 326, 124, 56, 236, 304, 146, 34, 214, 326, 124, 56, 236, 304, 146, 34, 214, 326, + 124, 56, 236, 304, 146, 34, 214, 326, 124, 56, 236, 304, 146, 34, 214, 326, 124, 56, 236, 304, + 145, 35, 215, 325, 125, 55, 235, 305, 145, 35, 215, 325, 125, 55, 235, 305, 145, 35, 215, 325, + 125, 55, 235, 305, 145, 35, 215, 325, 125, 55, 235, 305, 145, 35, 215, 325, 125, 55, 235, 305, + 145, 35, 215, 325, 125, 55, 235, 305, 145, 35, 215, 325, 125, 55, 235, 305, 144, 36, 216, 324, + 126, 54, 234, 306, 144, 36, 216, 324, 126, 54, 234, 306, 144, 36, 216, 324, 126, 54, 234, 306, + 144, 36, 216, 324, 126, 54, 234, 306, 144, 36, 216, 324, 126, 54, 234, 306, 144, 36, 216, 324, + 126, 54, 234, 306, 143, 37, 217, 323, 127, 53, 233, 307, 143, 37, 217, 323, 127, 53, 233, 307, + 143, 37, 217, 323, 127, 53, 233, 307, 143, 37, 217, 323, 127, 53, 233, 307, 143, 37, 217, 323, + 127, 53, 233, 307, 143, 37, 217, 323, 127, 53, 233, 307, 143, 37, 217, 323, 127, 53, 233, 307, + 143, 37, 217, 323, 127, 53, 233, 307, 142, 38, 218, 322, 128, 52, 232, 308, 142, 38, 218, 322, + 128, 52, 232, 308, 142, 38, 218, 322, 128, 52, 232, 308, 142, 38, 218, 322, 128, 52, 232, 308, + 142, 38, 218, 322, 128, 52, 232, 308, 142, 38, 218, 322, 128, 52, 232, 308, 142, 38, 218, 322, + 128, 52, 232, 308, 141, 39, 219, 321, 129, 51, 231, 309, 141, 39, 219, 321, 129, 51, 231, 309, + 141, 39, 219, 321, 129, 51, 231, 309, 141, 39, 219, 321, 129, 51, 231, 309, 141, 39, 219, 321, + 129, 51, 231, 309, 141, 39, 219, 321, 129, 51, 231, 309, 141, 39, 219, 321, 129, 51, 231, 309, + 140, 40, 220, 320, 130, 50, 230, 310, 140, 40, 220, 320, 130, 50, 230, 310, 140, 40, 220, 320, + 130, 50, 230, 310, 140, 40, 220, 320, 130, 50, 230, 310, 140, 40, 220, 320, 130, 50, 230, 310, + 140, 40, 220, 320, 130, 50, 230, 310, 140, 40, 220, 320, 130, 50, 230, 310, 140, 40, 220, 320, + 130, 50, 230, 310, 139, 41, 221, 319, 131, 49, 229, 311, 139, 41, 221, 319, 131, 49, 229, 311, + 139, 41, 221, 319, 131, 49, 229, 311, 139, 41, 221, 319, 131, 49, 229, 311, 139, 41, 221, 319, + 131, 49, 229, 311, 139, 41, 221, 319, 131, 49, 229, 311, 139, 41, 221, 319, 131, 49, 229, 311, + 139, 41, 221, 319, 131, 49, 229, 311, 138, 42, 222, 318, 132, 48, 228, 312, 138, 42, 222, 318, + 132, 48, 228, 312, 138, 42, 222, 318, 132, 48, 228, 312, 138, 42, 222, 318, 132, 48, 228, 312, + 138, 42, 222, 318, 132, 48, 228, 312, 138, 42, 222, 318, 132, 48, 228, 312, 138, 42, 222, 318, + 132, 48, 228, 312, 138, 42, 222, 318, 132, 48, 228, 312, 137, 43, 223, 317, 133, 47, 227, 313, + 137, 43, 223, 317, 133, 47, 227, 313, 137, 43, 223, 317, 133, 47, 227, 313, 137, 43, 223, 317, + 133, 47, 227, 313, 137, 43, 223, 317, 133, 47, 227, 313, 137, 43, 223, 317, 133, 47, 227, 313, + 137, 43, 223, 317, 133, 47, 227, 313, 137, 43, 223, 317, 133, 47, 227, 313, 137, 43, 223, 317, + 133, 47, 227, 313, 136, 44, 224, 316, 134, 46, 226, 314, 136, 44, 224, 316, 134, 46, 226, 314, + 136, 44, 224, 316, 134, 46, 226, 314, 136, 44, 224, 316, 134, 46, 226, 314, 136, 44, 224, 316, + 134, 46, 226, 314, 136, 44, 224, 316, 134, 46, 226, 314, 136, 44, 224, 316, 134, 46, 226, 314, + 136, 44, 224, 316, 134, 46, 226, 314, 135, 45, 225, 315, 135, 45, 225, 315, +}; + void InitSound() {} + } // namespace jak3 From bea9e6a1e395ea30bd16c2d121920f16f50b3fc8 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Fri, 26 Jan 2024 14:40:10 +0100 Subject: [PATCH 03/14] wip --- game/overlord/jak3/basefile.h | 4 +- game/overlord/jak3/basefilesystem.h | 7 +--- game/overlord/jak3/iso.cpp | 64 +++++++++++++++++++++++++++++ game/overlord/jak3/iso.h | 24 +++++++++++ game/overlord/jak3/iso_structs.h | 7 +--- game/overlord/jak3/overlord.h | 12 ++++-- game/overlord/jak3/pagemanager.h | 5 +-- game/overlord/jak3/ramdisk.cpp | 33 +++++++++++++++ game/overlord/jak3/ramdisk.h | 9 ++++ game/overlord/jak3/sbank.h | 5 +-- game/overlord/jak3/srpc.cpp | 54 ++++++++++++++++++++++++ game/overlord/jak3/srpc.h | 10 +++++ game/overlord/jak3/ssound.h | 39 ++++++++++++++++++ game/overlord/jak3/start.cpp | 52 +++++++++++++++++++++++ game/sce/iop.cpp | 6 +++ game/sce/iop.h | 1 + 16 files changed, 306 insertions(+), 26 deletions(-) create mode 100644 game/overlord/jak3/iso.cpp create mode 100644 game/overlord/jak3/iso.h create mode 100644 game/overlord/jak3/ramdisk.h create mode 100644 game/overlord/jak3/srpc.cpp create mode 100644 game/overlord/jak3/srpc.h create mode 100644 game/overlord/jak3/ssound.h diff --git a/game/overlord/jak3/basefile.h b/game/overlord/jak3/basefile.h index 6d6a2fe6c34..da71cfaa4eb 100644 --- a/game/overlord/jak3/basefile.h +++ b/game/overlord/jak3/basefile.h @@ -1,5 +1,4 @@ -#ifndef BASEFILE_H_ -#define BASEFILE_H_ +#pragma once #include "game/overlord/jak3/iso_structs.h" #include "game/overlord/jak3/overlord.h" @@ -18,4 +17,3 @@ class CBaseFile { }; } // namespace jak3 -#endif // BASEFILE_H_ diff --git a/game/overlord/jak3/basefilesystem.h b/game/overlord/jak3/basefilesystem.h index 2803428231f..18100f66e08 100644 --- a/game/overlord/jak3/basefilesystem.h +++ b/game/overlord/jak3/basefilesystem.h @@ -1,12 +1,11 @@ -#ifndef BASEFILESYSTEM_H_ -#define BASEFILESYSTEM_H_ +#pragma once #include "game/overlord/jak3/iso_structs.h" namespace jak3 { class CBaseFileSystem { public: - virtual void Init() = 0; + virtual int Init() = 0; virtual void PollDrive() = 0; virtual const ISOFileDef* Find(const char* name) = 0; virtual const ISOFileDef* FindIN(const char* name) = 0; @@ -16,5 +15,3 @@ class CBaseFileSystem { virtual VagDirEntryJak3* FindVagFile(const char* name) = 0; }; } // namespace jak3 - -#endif // BASEFILESYSTEM_H_ diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp new file mode 100644 index 00000000000..ab9790d1f09 --- /dev/null +++ b/game/overlord/jak3/iso.cpp @@ -0,0 +1,64 @@ +#include "iso.h" + +#include + +#include "game/overlord/jak3/basefilesystem.h" + +namespace jak3 { +using namespace iop; + +static int s_nISOInitFlag; +static ISO_LoadDGO s_LoadDGO; +int s_nSyncMbx; +CBaseFileSystem* g_pFileSystem; +MsgPacket s_MsgPacket_NotOnStackSync[2]; + +/* COMPLETE */ +void InitDriver() { + if (g_pFileSystem->Init() == 0) { + s_nISOInitFlag = 0; + } + + SendMbx(s_nSyncMbx, &s_MsgPacket_NotOnStackSync[0]); +} + +/* TODO unfinished */ +static int LookMbx() { + MsgPacket* pkt; + + int ret = PollMbx(&pkt, s_nSyncMbx); + if (ret != KE_MBOX_NOMSG) { + // FIXME + } + + return ret != KE_MBOX_NOMSG; +} + +/* COMPLETE */ +static void WaitMbx(int mbx) { + MsgPacket* pkt; + ReceiveMbx(&pkt, mbx); +} + +/* TODO unfinished */ +int InitISOFS(const char* fs_mode, const char* loading_sceeen) { + ThreadParam thp; + MbxParam mbx; + + memset(&s_LoadDGO, 0, sizeof(s_LoadDGO)); + s_nISOInitFlag = 1; + + return s_nISOInitFlag; +} + +/* COMPLETE */ +const ISOFileDef* FindISOFile(char* name) { + return g_pFileSystem->Find(name); +} + +/* COMPLETE */ +s32 GetISOFileLength(const ISOFileDef* fd) { + return g_pFileSystem->GetLength(fd); +} + +} // namespace jak3 diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h new file mode 100644 index 00000000000..7ce81b4d004 --- /dev/null +++ b/game/overlord/jak3/iso.h @@ -0,0 +1,24 @@ +#pragma once + +#include "game/sce/iop.h" + +namespace jak3 { + +struct ISOBuffer { + void AdjustDataLength(int); + void AdvanceCurrentData(int); +}; + +struct ISO_Hdr { + iop::MsgPacket msg; + + void SetActive(); + void SetUnk1(); + void SetUnk2(); +}; + +struct ISO_Msg : ISO_Hdr {}; + +struct ISO_LoadDGO : ISO_Msg {}; + +} // namespace jak3 diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index 7af569aa763..8e3b997c286 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -1,5 +1,4 @@ -#ifndef ISO_STRUCTS_H_ -#define ISO_STRUCTS_H_ +#pragma once #include "common/common_types.h" @@ -29,9 +28,5 @@ struct VagDirJak3 { struct VagDirEntry {}; -struct ISOBuffer {}; - struct ISOFileDef {}; } // namespace jak3 - -#endif // ISO_STRUCTS_H_ diff --git a/game/overlord/jak3/overlord.h b/game/overlord/jak3/overlord.h index 8fae9fe51f2..15261e4a636 100644 --- a/game/overlord/jak3/overlord.h +++ b/game/overlord/jak3/overlord.h @@ -1,9 +1,15 @@ -#ifndef OVERLORD_H_ -#define OVERLORD_H_ +#pragma once #include +#include "common/common_types.h" + namespace jak3 { + +struct Vec3 { + s32 x, y, z; +}; + enum class EIsoStatus { Unk }; int start_overlord_wrapper(int argc, const char* const* argv, bool* signal); @@ -14,5 +20,3 @@ void InitSound(); int VBlank_Initialize(); } // namespace jak3 - -#endif diff --git a/game/overlord/jak3/pagemanager.h b/game/overlord/jak3/pagemanager.h index 6c5e5283d1b..8ac7cc5a2df 100644 --- a/game/overlord/jak3/pagemanager.h +++ b/game/overlord/jak3/pagemanager.h @@ -1,5 +1,4 @@ -#ifndef PAGEMANAGER_H_ -#define PAGEMANAGER_H_ +#pragma once #include "common/common_types.h" @@ -40,5 +39,3 @@ class CPageManager { }; } // namespace jak3 - -#endif // PAGEMANAGER_H_ diff --git a/game/overlord/jak3/ramdisk.cpp b/game/overlord/jak3/ramdisk.cpp index e69de29bb2d..43a960253e9 100644 --- a/game/overlord/jak3/ramdisk.cpp +++ b/game/overlord/jak3/ramdisk.cpp @@ -0,0 +1,33 @@ +#include "ramdisk.h" + +#include "common/log/log.h" + +#include "game/sce/iop.h" + +namespace jak3 { +using namespace iop; + +static u8 gRamDisk_RPCBUF[40]; + +static void* RPC_Ramdisk(u32 fno, void* data, int size) { + lg::error("RPC_RAMDISK UNIMPLEMENTED"); + return nullptr; +} + +void InitRamdisk() {} + +u32 Thread_Server() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab2, RPC_Ramdisk, gRamDisk_RPCBUF, nullptr, nullptr, &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/ramdisk.h b/game/overlord/jak3/ramdisk.h new file mode 100644 index 00000000000..f081874264e --- /dev/null +++ b/game/overlord/jak3/ramdisk.h @@ -0,0 +1,9 @@ +#pragma once + +#include "common/common_types.h" + +namespace jak3 { + +u32 Thread_Server(); + +} diff --git a/game/overlord/jak3/sbank.h b/game/overlord/jak3/sbank.h index 310f890ef34..69a41942380 100644 --- a/game/overlord/jak3/sbank.h +++ b/game/overlord/jak3/sbank.h @@ -1,5 +1,4 @@ -#ifndef SBANK_H_ -#define SBANK_H_ +#pragma once #include "common/common_types.h" @@ -18,5 +17,3 @@ struct SoundBankInfo { }; void InitBanks(); } // namespace jak3 - -#endif // SBANK_H_ diff --git a/game/overlord/jak3/srpc.cpp b/game/overlord/jak3/srpc.cpp new file mode 100644 index 00000000000..caf82f752ba --- /dev/null +++ b/game/overlord/jak3/srpc.cpp @@ -0,0 +1,54 @@ +#include "srpc.h" + +#include "common/log/log.h" + +#include "game/sce/iop.h" + +namespace jak3 { +using namespace iop; + +constexpr int SRPC_MESSAGE_SIZE = 0x50; +constexpr int SRPC_MESSAGE_COUNT = 128; + +static u8 s_anSRPC_PlayerBuf[SRPC_MESSAGE_SIZE * SRPC_MESSAGE_COUNT]; +static u8 s_anSRPC_LoaderBuf[SRPC_MESSAGE_SIZE]; + +static void* RPC_Player(u32 fno, void* data, int size) { + lg::error("RPC_PLAYER UNIMPLEMENTED"); + return nullptr; +} + +static void* RPC_Loader(u32 fno, void* data, int size) { + lg::error("RPC_LOADER UNIMPLEMENTED"); + return nullptr; +} + +u32 Thread_Player() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab0, RPC_Player, s_anSRPC_PlayerBuf, nullptr, nullptr, &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +u32 Thread_Loader() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab1, RPC_Loader, s_anSRPC_LoaderBuf, nullptr, nullptr, &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/srpc.h b/game/overlord/jak3/srpc.h new file mode 100644 index 00000000000..c255741108b --- /dev/null +++ b/game/overlord/jak3/srpc.h @@ -0,0 +1,10 @@ +#pragma once + +#include "common/common_types.h" + +namespace jak3 { + +u32 Thread_Player(); +u32 Thread_Loader(); + +} // namespace jak3 diff --git a/game/overlord/jak3/ssound.h b/game/overlord/jak3/ssound.h new file mode 100644 index 00000000000..0fc21dad01b --- /dev/null +++ b/game/overlord/jak3/ssound.h @@ -0,0 +1,39 @@ +#pragma once + +#include "common/common_types.h" + +#include "game/overlord/jak3/overlord.h" + +namespace jak3 { + +struct Curve { + s32 p1; + s32 p2; + s32 p3; + s32 p4; +}; + +struct SoundPlayParams { + u16 mask; + s16 pitch_mod; + s16 bend; + s16 fo_min; + s16 fo_max; + s8 fo_curve; + s8 priority; + s32 volume; + Vec3 trans; + u8 group; + u8 reg[3]; +}; + +struct SoundInfo { + char name[16]; + s32 id; + u32 sound_handle; + s32 auto_volume; + s32 auto_time; + SoundPlayParams params; +}; + +} // namespace jak3 diff --git a/game/overlord/jak3/start.cpp b/game/overlord/jak3/start.cpp index f53da86a3e8..4b1695b6d2b 100644 --- a/game/overlord/jak3/start.cpp +++ b/game/overlord/jak3/start.cpp @@ -2,13 +2,19 @@ #include #include "overlord.h" +#include "ramdisk.h" #include "sbank.h" +#include "game/overlord/jak3/srpc.h" #include "game/sce/iop.h" namespace jak3 { using namespace iop; +int g_nServerThreadID; +int g_nPlayerThreadID; +int g_nLoaderThreadID; + int start_overlord(int argc, const char* const* argp) { ThreadParam thp; @@ -31,6 +37,52 @@ int start_overlord(int argc, const char* const* argp) { InitSound(); VBlank_Initialize(); + thp.attr = TH_C; + thp.option = 0; + thp.entry = Thread_Server; + thp.stackSize = 0x800; + thp.initPriority = 59; + g_nServerThreadID = CreateThread(&thp); + if (g_nServerThreadID < 0) { + Panic(); + return 1; + } + + thp.attr = TH_C; + thp.option = 0; + thp.entry = Thread_Player; + thp.stackSize = 0xb00; + thp.initPriority = 54; + g_nPlayerThreadID = CreateThread(&thp); + if (g_nPlayerThreadID < 0) { + Panic(); + return 1; + } + + thp.attr = TH_C; + thp.option = 0; + thp.entry = Thread_Loader; + thp.stackSize = 0x900; + thp.initPriority = 58; + g_nLoaderThreadID = CreateThread(&thp); + if (g_nPlayerThreadID < 0) { + Panic(); + return 1; + } + + //CDvdDriver::Initialize(&g_DvdDriver); + InitISOFS(argp[1], argp[2]); + + StartThread(g_nServerThreadID, 0); + StartThread(g_nPlayerThreadID, 0); + StartThread(g_nLoaderThreadID, 0); + + printf("======== overlrd2.irx post-startup ========\n"); + // printf(" mem size: %lu\n", QueryMemSize()); + // printf("total mem free: %lu\n", QueryTotalFreeMemSize()); + // printf(" max mem free: %lu\n", QueryMaxFreeMemSize()); + // printf(" used: %lu\n", QueryMemSize() - QueryTotalFreeMemSize()); + return 0; } diff --git a/game/sce/iop.cpp b/game/sce/iop.cpp index 2784c9fa424..66b4c25e8c6 100644 --- a/game/sce/iop.cpp +++ b/game/sce/iop.cpp @@ -195,6 +195,12 @@ s32 SendMbx(s32 mbxid, void* sendmsg) { return iop->kernel.SendMbx(mbxid, sendmsg); } +s32 ReceiveMbx(MsgPacket** recvmsg, int mbxid) { + ASSERT(false); + // TODO + return 0; +} + s32 PollMbx(MsgPacket** recvmsg, int mbxid) { return iop->kernel.PollMbx((void**)recvmsg, mbxid); } diff --git a/game/sce/iop.h b/game/sce/iop.h index 50a06088c1b..d1de2f65758 100644 --- a/game/sce/iop.h +++ b/game/sce/iop.h @@ -134,6 +134,7 @@ int sceCdDiskReady(int mode); u32 sceSifSetDma(sceSifDmaData* sdd, int len); s32 SendMbx(int mbxid, void* sendmsg); +s32 ReceiveMbx(MsgPacket** recvmsg, int mbxid); s32 PollMbx(MsgPacket** recvmsg, int mbxid); s32 PeekMbx(s32 mbx); s32 CreateMbx(MbxParam* param); From 7661301b5f93beac54c26fad59d9700242c7f4d4 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sat, 27 Jan 2024 19:44:20 +0100 Subject: [PATCH 04/14] overlrd2: ctz --- game/overlord/jak3/pagemanager.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 game/overlord/jak3/pagemanager.cpp diff --git a/game/overlord/jak3/pagemanager.cpp b/game/overlord/jak3/pagemanager.cpp new file mode 100644 index 00000000000..c6be36f641e --- /dev/null +++ b/game/overlord/jak3/pagemanager.cpp @@ -0,0 +1,20 @@ +#include "pagemanager.h" + +namespace jak3 { + +static inline int ctz(u32 x) { + // Isolate lowest bit and subtract 1 + x = (x & -x) - 1; + + // popcount + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += (x >> 8); + x += (x >> 16); + x &= 0x3f; + + return static_cast(x); +} + +} // namespace jak3 From 379622b70babbba20cfa0690c1373125b8f31fa9 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Wed, 1 May 2024 06:30:34 +0200 Subject: [PATCH 05/14] set up fake iso system class --- game/CMakeLists.txt | 5 +++++ game/overlord/jak3/basefile.h | 4 ++-- game/overlord/jak3/iso.cpp | 26 +++++++++++++++++++++++ game/overlord/jak3/iso.h | 1 + game/overlord/jak3/iso_fake.cpp | 36 ++++++++++++++++++++++++++++++++ game/overlord/jak3/iso_fake.h | 35 +++++++++++++++++++++++++++++++ game/overlord/jak3/iso_structs.h | 2 +- game/overlord/jak3/ramdisk.cpp | 3 ++- game/overlord/jak3/srpc.cpp | 6 ++++-- game/overlord/jak3/start.cpp | 3 ++- game/runtime.cpp | 6 +++++- 11 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 game/overlord/jak3/iso_fake.cpp create mode 100644 game/overlord/jak3/iso_fake.h diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 4e2997a7188..4aa8ff4ccb7 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -252,8 +252,13 @@ set(RUNTIME_SOURCE overlord/jak2/streamlist.cpp overlord/jak2/vag.cpp overlord/jak3/start.cpp + overlord/jak3/iso_fake.cpp + overlord/jak3/iso.cpp overlord/jak3/overlord.cpp + overlord/jak3/pagemanager.cpp + overlord/jak3/ramdisk.cpp overlord/jak3/sbank.cpp + overlord/jak3/srpc.cpp overlord/jak3/ssound.cpp overlord/jak3/vblank_handler.cpp runtime.cpp diff --git a/game/overlord/jak3/basefile.h b/game/overlord/jak3/basefile.h index da71cfaa4eb..1c0225b4452 100644 --- a/game/overlord/jak3/basefile.h +++ b/game/overlord/jak3/basefile.h @@ -1,5 +1,6 @@ #pragma once +#include "game/overlord/jak3/iso.h" #include "game/overlord/jak3/iso_structs.h" #include "game/overlord/jak3/overlord.h" @@ -11,9 +12,8 @@ class CBaseFile { virtual EIsoStatus SyncRead() = 0; virtual void Close() = 0; - /* unk return values */ + /* unk return values */ virtual void Unk1() = 0; virtual void Unk2() = 0; }; } // namespace jak3 - diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index ab9790d1f09..d5d69aebcbb 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -2,7 +2,11 @@ #include +#include "common/log/log.h" + +#include "game/common/dgo_rpc_types.h" #include "game/overlord/jak3/basefilesystem.h" +#include "game/overlord/jak3/iso_fake.h" namespace jak3 { using namespace iop; @@ -12,6 +16,27 @@ static ISO_LoadDGO s_LoadDGO; int s_nSyncMbx; CBaseFileSystem* g_pFileSystem; MsgPacket s_MsgPacket_NotOnStackSync[2]; +RPC_Dgo_Cmd s_aISO_RPCBuf[1]; + +static void* RPC_DGO(u32 fno, void* data, int size) { + lg::error("RPC_DGO UNIMPLEMENTED"); + return nullptr; +} + +static u32 DGOThread() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab3, RPC_DGO, s_aISO_RPCBuf, sizeof(s_aISO_RPCBuf), nullptr, nullptr, + &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} /* COMPLETE */ void InitDriver() { @@ -47,6 +72,7 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { memset(&s_LoadDGO, 0, sizeof(s_LoadDGO)); s_nISOInitFlag = 1; + g_pFileSystem = &g_FakeISOCDFileSystem; return s_nISOInitFlag; } diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h index 7ce81b4d004..4e03d677f4c 100644 --- a/game/overlord/jak3/iso.h +++ b/game/overlord/jak3/iso.h @@ -21,4 +21,5 @@ struct ISO_Msg : ISO_Hdr {}; struct ISO_LoadDGO : ISO_Msg {}; +int InitISOFS(const char* fs_mode, const char* loading_sceeen); } // namespace jak3 diff --git a/game/overlord/jak3/iso_fake.cpp b/game/overlord/jak3/iso_fake.cpp new file mode 100644 index 00000000000..23ba9a246bc --- /dev/null +++ b/game/overlord/jak3/iso_fake.cpp @@ -0,0 +1,36 @@ +#include "iso_fake.h" + +namespace jak3 { +CFakeISOCDFileSystem g_FakeISOCDFileSystem; + +int CFakeISOCDFileSystem::Init() { + return 0; +} + +void CFakeISOCDFileSystem::PollDrive() {} + +const ISOFileDef* CFakeISOCDFileSystem::Find(const char* name) { + return nullptr; +} + +const ISOFileDef* CFakeISOCDFileSystem::FindIN(const char* name) { + return nullptr; +} + +int CFakeISOCDFileSystem::GetLength(const ISOFileDef* def) { + return 0; +} + +int CFakeISOCDFileSystem::Open(const ISOFileDef* def, int offset, EFileComp mode) { + return 0; +} + +int CFakeISOCDFileSystem::OpenWad(const ISOFileDef* def, int offset) { + return 0; +} + +VagDirEntryJak3* CFakeISOCDFileSystem::FindVagFile(const char* name) { + return nullptr; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/iso_fake.h b/game/overlord/jak3/iso_fake.h new file mode 100644 index 00000000000..b73d3aac934 --- /dev/null +++ b/game/overlord/jak3/iso_fake.h @@ -0,0 +1,35 @@ +#ifndef ISO_FAKE_H_ +#define ISO_FAKE_H_ + +#include "basefile.h" +#include "basefilesystem.h" + +#include "game/overlord/jak3/iso.h" + +namespace jak3 { +class CFakeISOCDFileSystem : public CBaseFileSystem { + int Init() override; + void PollDrive() override; + const ISOFileDef* Find(const char* name) override; + const ISOFileDef* FindIN(const char* name) override; + int GetLength(const ISOFileDef* def) override; + int Open(const ISOFileDef* def, int offset, EFileComp mode) override; + int OpenWad(const ISOFileDef* def, int offset) override; + VagDirEntryJak3* FindVagFile(const char* name) override; +}; + +class CFakeISOCDFile : public CBaseFile { + EIsoStatus BeginRead(ISOBuffer*) override; + EIsoStatus SyncRead() override; + void Close() override; + + /* unk return values */ + void Unk1() override; + void Unk2() override; +}; + +extern CFakeISOCDFileSystem g_FakeISOCDFileSystem; + +} // namespace jak3 + +#endif // ISO_FAKE_H_ diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index 8e3b997c286..68cb5d2fd19 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -24,7 +24,7 @@ struct VagDirJak3 { u32 version; u32 count; VagDirEntryJak3 entries[0]; -} dir; +}; struct VagDirEntry {}; diff --git a/game/overlord/jak3/ramdisk.cpp b/game/overlord/jak3/ramdisk.cpp index 43a960253e9..09e285c72ca 100644 --- a/game/overlord/jak3/ramdisk.cpp +++ b/game/overlord/jak3/ramdisk.cpp @@ -23,7 +23,8 @@ u32 Thread_Server() { CpuDisableIntr(); sceSifInitRpc(0); sceSifSetRpcQueue(&dq, GetThreadId()); - sceSifRegisterRpc(&serve, 0xfab2, RPC_Ramdisk, gRamDisk_RPCBUF, nullptr, nullptr, &dq); + sceSifRegisterRpc(&serve, 0xfab2, RPC_Ramdisk, gRamDisk_RPCBUF, sizeof(gRamDisk_RPCBUF), nullptr, + nullptr, &dq); CpuEnableIntr(); sceSifRpcLoop(&dq); diff --git a/game/overlord/jak3/srpc.cpp b/game/overlord/jak3/srpc.cpp index caf82f752ba..f3b9a547099 100644 --- a/game/overlord/jak3/srpc.cpp +++ b/game/overlord/jak3/srpc.cpp @@ -30,7 +30,8 @@ u32 Thread_Player() { CpuDisableIntr(); sceSifInitRpc(0); sceSifSetRpcQueue(&dq, GetThreadId()); - sceSifRegisterRpc(&serve, 0xfab0, RPC_Player, s_anSRPC_PlayerBuf, nullptr, nullptr, &dq); + sceSifRegisterRpc(&serve, 0xfab0, RPC_Player, s_anSRPC_PlayerBuf, sizeof(s_anSRPC_PlayerBuf), + nullptr, nullptr, &dq); CpuEnableIntr(); sceSifRpcLoop(&dq); @@ -44,7 +45,8 @@ u32 Thread_Loader() { CpuDisableIntr(); sceSifInitRpc(0); sceSifSetRpcQueue(&dq, GetThreadId()); - sceSifRegisterRpc(&serve, 0xfab1, RPC_Loader, s_anSRPC_LoaderBuf, nullptr, nullptr, &dq); + sceSifRegisterRpc(&serve, 0xfab1, RPC_Loader, s_anSRPC_LoaderBuf, sizeof(s_anSRPC_LoaderBuf), + nullptr, nullptr, &dq); CpuEnableIntr(); sceSifRpcLoop(&dq); diff --git a/game/overlord/jak3/start.cpp b/game/overlord/jak3/start.cpp index 4b1695b6d2b..4b08ce29a69 100644 --- a/game/overlord/jak3/start.cpp +++ b/game/overlord/jak3/start.cpp @@ -1,6 +1,7 @@ #include #include +#include "iso.h" #include "overlord.h" #include "ramdisk.h" #include "sbank.h" @@ -70,7 +71,7 @@ int start_overlord(int argc, const char* const* argp) { return 1; } - //CDvdDriver::Initialize(&g_DvdDriver); + // CDvdDriver::Initialize(&g_DvdDriver); InitISOFS(argp[1], argp[2]); StartThread(g_nServerThreadID, 0); diff --git a/game/runtime.cpp b/game/runtime.cpp index b39317b604b..b1a2347cd63 100644 --- a/game/runtime.cpp +++ b/game/runtime.cpp @@ -4,6 +4,7 @@ */ #include "common/common_types.h" + #ifdef OS_POSIX #include @@ -78,6 +79,7 @@ #include "game/overlord/jak2/stream.h" #include "game/overlord/jak2/streamlist.h" #include "game/overlord/jak2/vag.h" +#include "game/overlord/jak3/overlord.h" #include "game/system/Deci2Server.h" #include "game/system/iop_thread.h" #include "sce/deci2.h" @@ -323,9 +325,11 @@ void iop_runner(SystemThreadInterface& iface, GameVersion version) { jak1::start_overlord_wrapper(iop.overlord_argc, iop.overlord_argv, &complete); break; case GameVersion::Jak2: - case GameVersion::Jak3: // TODO: jak3 using jak2's overlord. jak2::start_overlord_wrapper(iop.overlord_argc, iop.overlord_argv, &complete); break; + case GameVersion::Jak3: + jak3::start_overlord_wrapper(iop.overlord_argc, iop.overlord_argv, &complete); + break; default: ASSERT_NOT_REACHED(); } From 541815f809ce18c8ab85b58bb26b5dd83ffab66e Mon Sep 17 00:00:00 2001 From: Ziemas Date: Wed, 1 May 2024 06:48:43 +0200 Subject: [PATCH 06/14] start all rpc threads --- game/CMakeLists.txt | 1 + game/overlord/jak3/iso.cpp | 38 +++++++++++++++++++++--- game/overlord/jak3/stream.cpp | 54 +++++++++++++++++++++++++++++++++++ game/overlord/jak3/stream.h | 11 +++++++ 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 game/overlord/jak3/stream.cpp create mode 100644 game/overlord/jak3/stream.h diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 4aa8ff4ccb7..db544438747 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -260,6 +260,7 @@ set(RUNTIME_SOURCE overlord/jak3/sbank.cpp overlord/jak3/srpc.cpp overlord/jak3/ssound.cpp + overlord/jak3/stream.cpp overlord/jak3/vblank_handler.cpp runtime.cpp sce/deci2.cpp diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index d5d69aebcbb..4448c09acad 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -7,16 +7,21 @@ #include "game/common/dgo_rpc_types.h" #include "game/overlord/jak3/basefilesystem.h" #include "game/overlord/jak3/iso_fake.h" +#include "game/overlord/jak3/stream.h" namespace jak3 { using namespace iop; +CBaseFileSystem* g_pFileSystem; +int g_nDGOThreadID; +int g_nSTRThreadID; +int g_nPlayThreadID; + static int s_nISOInitFlag; static ISO_LoadDGO s_LoadDGO; -int s_nSyncMbx; -CBaseFileSystem* g_pFileSystem; -MsgPacket s_MsgPacket_NotOnStackSync[2]; -RPC_Dgo_Cmd s_aISO_RPCBuf[1]; +static int s_nSyncMbx; +static MsgPacket s_MsgPacket_NotOnStackSync[2]; +static RPC_Dgo_Cmd s_aISO_RPCBuf[1]; static void* RPC_DGO(u32 fno, void* data, int size) { lg::error("RPC_DGO UNIMPLEMENTED"); @@ -74,6 +79,31 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { s_nISOInitFlag = 1; g_pFileSystem = &g_FakeISOCDFileSystem; + thp.attr = TH_C; + thp.entry = DGOThread; + thp.initPriority = 0x38; + thp.option = 0; + thp.stackSize = 0x900; + g_nDGOThreadID = CreateThread(&thp); + + thp.attr = TH_C; + thp.entry = STRThread; + thp.initPriority = 0x39; + thp.option = 0; + thp.stackSize = 0x900; + g_nSTRThreadID = CreateThread(&thp); + + thp.attr = TH_C; + thp.entry = PLAYThread; + thp.initPriority = 0x35; + thp.option = 0; + thp.stackSize = 0x900; + g_nPlayThreadID = CreateThread(&thp); + + StartThread(g_nDGOThreadID, 0); + StartThread(g_nSTRThreadID, 0); + StartThread(g_nPlayThreadID, 0); + return s_nISOInitFlag; } diff --git a/game/overlord/jak3/stream.cpp b/game/overlord/jak3/stream.cpp new file mode 100644 index 00000000000..ca5e30d5d0b --- /dev/null +++ b/game/overlord/jak3/stream.cpp @@ -0,0 +1,54 @@ +#include "common/common_types.h" +#include "common/log/log.h" + +#include "game/common/str_rpc_types.h" +#include "game/sce/iop.h" + +namespace jak3 { +using namespace iop; + +static RPC_Str_Cmd_Jak2 sRPCBuf[1]; +static RPC_Str_Cmd_Jak2 sRPCBuf2[4]; + +static void* RPC_STR(unsigned int /*fno*/, void* _cmd, int /*y*/); +static void* RPC_PLAY(unsigned int /*fno*/, void* _cmd, int size); + +u32 STRThread() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab4, RPC_STR, sRPCBuf, sizeof(sRPCBuf), nullptr, nullptr, &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +u32 PLAYThread() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab5, RPC_PLAY, sRPCBuf2, sizeof(sRPCBuf2), nullptr, nullptr, &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +static void* RPC_STR(unsigned int /*fno*/, void* _cmd, int /*y*/) { + lg::error("RPC_STR UNIMPLEMENTED"); + return nullptr; +} + +static void* RPC_PLAY(unsigned int /*fno*/, void* _cmd, int size) { + lg::error("RPC_PLAY UNIMPLEMENTED"); + return nullptr; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/stream.h b/game/overlord/jak3/stream.h new file mode 100644 index 00000000000..6938dc80048 --- /dev/null +++ b/game/overlord/jak3/stream.h @@ -0,0 +1,11 @@ +#ifndef STREAM_H_ +#define STREAM_H_ + +#include "common/common_types.h" + +namespace jak3 { +u32 STRThread(); +u32 PLAYThread(); +} // namespace jak3 + +#endif // STREAM_H_ From 38fe4161d0413572996a834ee9a060d8b8539f60 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Wed, 1 May 2024 23:55:00 +0200 Subject: [PATCH 07/14] wip --- game/common/dgo_rpc_types.h | 4 +- game/overlord/jak3/basefile.h | 1 - game/overlord/jak3/iso.cpp | 106 +++++++++++++++++++++++++------ game/overlord/jak3/iso.h | 24 ++++--- game/overlord/jak3/iso_structs.h | 5 ++ 5 files changed, 110 insertions(+), 30 deletions(-) diff --git a/game/common/dgo_rpc_types.h b/game/common/dgo_rpc_types.h index 14e7523e335..f4b6709f43e 100644 --- a/game/common/dgo_rpc_types.h +++ b/game/common/dgo_rpc_types.h @@ -40,8 +40,8 @@ struct RPC_Dgo_Cmd { uint32_t buffer2; uint32_t buffer_heap_top; char name[16]; - uint16_t cgo_id; - uint8_t pad[30]; + uint32_t cgo_id; + uint8_t pad[28]; }; static_assert(sizeof(RPC_Dgo_Cmd) == 0x40); } // namespace jak3 diff --git a/game/overlord/jak3/basefile.h b/game/overlord/jak3/basefile.h index 1c0225b4452..b5ec389955b 100644 --- a/game/overlord/jak3/basefile.h +++ b/game/overlord/jak3/basefile.h @@ -1,6 +1,5 @@ #pragma once -#include "game/overlord/jak3/iso.h" #include "game/overlord/jak3/iso_structs.h" #include "game/overlord/jak3/overlord.h" diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index 4448c09acad..bf8c1d50474 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -13,35 +13,21 @@ namespace jak3 { using namespace iop; CBaseFileSystem* g_pFileSystem; +int g_nISOThreadID; int g_nDGOThreadID; int g_nSTRThreadID; int g_nPlayThreadID; +int g_nISOMbx; static int s_nISOInitFlag; static ISO_LoadDGO s_LoadDGO; static int s_nSyncMbx; static MsgPacket s_MsgPacket_NotOnStackSync[2]; static RPC_Dgo_Cmd s_aISO_RPCBuf[1]; +static int s_nDGOMbx; -static void* RPC_DGO(u32 fno, void* data, int size) { - lg::error("RPC_DGO UNIMPLEMENTED"); - return nullptr; -} - -static u32 DGOThread() { - sceSifQueueData dq; - sceSifServeData serve; - - CpuDisableIntr(); - sceSifInitRpc(0); - sceSifSetRpcQueue(&dq, GetThreadId()); - sceSifRegisterRpc(&serve, 0xfab3, RPC_DGO, s_aISO_RPCBuf, sizeof(s_aISO_RPCBuf), nullptr, nullptr, - &dq); - CpuEnableIntr(); - sceSifRpcLoop(&dq); - - return 0; -} +static u32 DGOThread(); +u32 ISOThread(); /* COMPLETE */ void InitDriver() { @@ -79,6 +65,25 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { s_nISOInitFlag = 1; g_pFileSystem = &g_FakeISOCDFileSystem; + mbx.attr = 0; + mbx.option = 0; + g_nISOMbx = CreateMbx(&mbx); + + mbx.attr = 0; + mbx.option = 0; + s_nDGOMbx = CreateMbx(&mbx); + + mbx.attr = 0; + mbx.option = 0; + s_nSyncMbx = CreateMbx(&mbx); + + thp.attr = TH_C; + thp.entry = ISOThread; + thp.initPriority = 0x37; + thp.option = 0; + thp.stackSize = 0x1100; + g_nISOThreadID = CreateThread(&thp); + thp.attr = TH_C; thp.entry = DGOThread; thp.initPriority = 0x38; @@ -100,6 +105,7 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { thp.stackSize = 0x900; g_nPlayThreadID = CreateThread(&thp); + StartThread(g_nISOThreadID, 0); StartThread(g_nDGOThreadID, 0); StartThread(g_nSTRThreadID, 0); StartThread(g_nPlayThreadID, 0); @@ -107,6 +113,68 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { return s_nISOInitFlag; } +u32 ISOThread() { + while (true) { + DelayThread(4000); + } + + return 0; +} + +static void ISO_LoadDGO(RPC_Dgo_Cmd* msg); +static void ISO_LoadNextDGO(RPC_Dgo_Cmd* msg); +static void ISO_CancelDGO(RPC_Dgo_Cmd* msg); + +static void* RPC_DGO(u32 fno, void* data, int size) { + auto* msg = static_cast(data); + + switch (fno) { + case 0: + ISO_LoadDGO(msg); + break; + case 1: + ISO_LoadNextDGO(msg); + break; + case 2: + ISO_CancelDGO(msg); + break; + default: + msg->result = 1; + break; + } + return data; +} + +static u32 DGOThread() { + sceSifQueueData dq; + sceSifServeData serve; + + CpuDisableIntr(); + sceSifInitRpc(0); + sceSifSetRpcQueue(&dq, GetThreadId()); + sceSifRegisterRpc(&serve, 0xfab3, RPC_DGO, s_aISO_RPCBuf, sizeof(s_aISO_RPCBuf), nullptr, nullptr, + &dq); + CpuEnableIntr(); + sceSifRpcLoop(&dq); + + return 0; +} + +static void ISO_LoadDGO(RPC_Dgo_Cmd* msg) { + auto* def = g_pFileSystem->Find(msg->name); + if (def == nullptr) { + msg->result = 1; + return; + } + + msg->buffer1 = msg->buffer_heap_top; + msg->result = 0; +} + +static void ISO_LoadNextDGO(RPC_Dgo_Cmd* msg) {} + +static void ISO_CancelDGO(RPC_Dgo_Cmd* msg) {} + /* COMPLETE */ const ISOFileDef* FindISOFile(char* name) { return g_pFileSystem->Find(name); diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h index 4e03d677f4c..d8fd39abab7 100644 --- a/game/overlord/jak3/iso.h +++ b/game/overlord/jak3/iso.h @@ -1,25 +1,33 @@ #pragma once +#include "game/overlord/jak3/basefile.h" #include "game/sce/iop.h" namespace jak3 { -struct ISOBuffer { - void AdjustDataLength(int); - void AdvanceCurrentData(int); -}; - struct ISO_Hdr { - iop::MsgPacket msg; + iop::MsgPacket m_Pkt; + int m_nStatus; + bool m_bActive; + bool unk1; + bool unk2; void SetActive(); void SetUnk1(); void SetUnk2(); }; -struct ISO_Msg : ISO_Hdr {}; +struct ISO_Msg : ISO_Hdr { + u32 cmd_kind; + int mbx_to_reply; + int thread_id; + void* callback; + CBaseFile* file; +}; -struct ISO_LoadDGO : ISO_Msg {}; +struct ISO_LoadDGO : ISO_Msg { + ISOFileDef* fd; +}; int InitISOFS(const char* fs_mode, const char* loading_sceeen); } // namespace jak3 diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index 68cb5d2fd19..2c66fdcaea6 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -6,6 +6,11 @@ namespace jak3 { /* TODO check values */ enum class EFileComp { MODE0, MODE1, KNOWN_NOT_BLZO }; +struct ISOBuffer { + void AdjustDataLength(int); + void AdvanceCurrentData(int); +}; + struct VagDirEntryJak3 { union { u64 data; From 3c730639403b109102cbe22605274b1b2a5a59cc Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 2 May 2024 06:20:37 +0200 Subject: [PATCH 08/14] iop: Support wating on message boxes --- game/sce/iop.cpp | 4 +- game/sce/iop.h | 6 +++ game/system/IOP_Kernel.cpp | 81 ++++++++++++++++++++++++++++++++++++++ game/system/IOP_Kernel.h | 59 ++++++--------------------- 4 files changed, 101 insertions(+), 49 deletions(-) diff --git a/game/sce/iop.cpp b/game/sce/iop.cpp index 66b4c25e8c6..feeafe90ea2 100644 --- a/game/sce/iop.cpp +++ b/game/sce/iop.cpp @@ -196,9 +196,7 @@ s32 SendMbx(s32 mbxid, void* sendmsg) { } s32 ReceiveMbx(MsgPacket** recvmsg, int mbxid) { - ASSERT(false); - // TODO - return 0; + return iop->kernel.ReceiveMbx((void**)recvmsg, mbxid); } s32 PollMbx(MsgPacket** recvmsg, int mbxid) { diff --git a/game/sce/iop.h b/game/sce/iop.h index d1de2f65758..216faee08fd 100644 --- a/game/sce/iop.h +++ b/game/sce/iop.h @@ -30,6 +30,12 @@ #define SA_THFIFO 0 #define SA_THPRI 1 +// Message box attributes +#define MBA_THFIFO 0x000 +#define MBA_THPRI 0x001 +#define MBA_MSFIFO 0x000 +#define MBA_MSPRI 0x004 + class IOP; namespace iop { diff --git a/game/system/IOP_Kernel.cpp b/game/system/IOP_Kernel.cpp index 10ce6e88fa9..b3dcfca8036 100644 --- a/game/system/IOP_Kernel.cpp +++ b/game/system/IOP_Kernel.cpp @@ -103,6 +103,12 @@ void IOP_Kernel::iWakeupThread(s32 id) { wakeup_queue.push(id); } +s32 IOP_Kernel::CreateSema(s32 attr, s32 option, s32 init_count, s32 max_count) { + s32 id = semas.size(); + semas.emplace_back((Semaphore::attribute)attr, option, init_count, max_count); + return id; +} + s32 IOP_Kernel::WaitSema(s32 id) { auto& sema = semas.at(id); if (sema.count > 0) { @@ -159,6 +165,81 @@ s32 IOP_Kernel::PollSema(s32 id) { return KE_SEMA_ZERO; } +/*! + * Create a message box + */ +s32 IOP_Kernel::CreateMbx() { + s32 id = mbxs.size(); + mbxs.emplace_back(); + return id; +} + +s32 IOP_Kernel::ReceiveMbx(void** msg, s32 mbx) { + ASSERT(mbx < (s32)mbxs.size()); + s32 gotSomething = mbxs[mbx].messages.empty() ? 0 : 1; + if (!gotSomething) { + /* Was empty, wait until there's messages */ + mbxs[mbx].wait_list.push_back(_currentThread); + _currentThread->state = IopThread::State::Wait; + _currentThread->waitType = IopThread::Wait::MsgBox; + leaveThread(); + } + + ASSERT(mbxs[mbx].messages.empty() == false); + + void* thing = mbxs[mbx].messages.front(); + if (msg) { + *msg = thing; + } + + mbxs[mbx].messages.pop(); + + return KE_OK; +} + +/*! + * Set msg to thing if its there and pop it. + * Returns if it got something. + */ +s32 IOP_Kernel::PollMbx(void** msg, s32 mbx) { + ASSERT(mbx < (s32)mbxs.size()); + s32 gotSomething = mbxs[mbx].messages.empty() ? 0 : 1; + if (gotSomething) { + void* thing = mbxs[mbx].messages.front(); + + if (msg) { + *msg = thing; + } + + mbxs[mbx].messages.pop(); + } + + return gotSomething ? KE_OK : KE_MBOX_NOMSG; +} + +s32 IOP_Kernel::PeekMbx(s32 mbx) { + return !mbxs[mbx].messages.empty(); +} + +/*! + * Push something into a mbx + */ +s32 IOP_Kernel::SendMbx(s32 mbx, void* value) { + ASSERT(mbx < (s32)mbxs.size()); + mbxs[mbx].messages.push(value); + + IopThread* to_run = nullptr; + if (!mbxs[mbx].wait_list.empty()) { + to_run = mbxs[mbx].wait_list.front(); + mbxs[mbx].wait_list.pop_front(); + + to_run->waitType = IopThread::Wait::None; + to_run->state = IopThread::State::Ready; + } + + return KE_OK; +} + /*! * Return to kernel from a thread, not to be called from the kernel thread. */ diff --git a/game/system/IOP_Kernel.h b/game/system/IOP_Kernel.h index b8a5b513895..1ad01a66e6f 100644 --- a/game/system/IOP_Kernel.h +++ b/game/system/IOP_Kernel.h @@ -57,6 +57,7 @@ struct IopThread { None, Semaphore, Delay, + MsgBox, }; IopThread(std::string n, void (*f)(), s32 ID, u32 priority) @@ -91,6 +92,11 @@ struct Semaphore { std::list wait_list; }; +struct MsgBox { + std::queue messages; + std::list wait_list; +}; + class IOP_Kernel { public: IOP_Kernel() { @@ -122,52 +128,13 @@ class IOP_Kernel { return _currentThread->thID; } - /*! - * Create a message box - */ - s32 CreateMbx() { - s32 id = mbxs.size(); - mbxs.emplace_back(); - return id; - } - - /*! - * Set msg to thing if its there and pop it. - * Returns if it got something. - */ - s32 PollMbx(void** msg, s32 mbx) { - ASSERT(mbx < (s32)mbxs.size()); - s32 gotSomething = mbxs[mbx].empty() ? 0 : 1; - if (gotSomething) { - void* thing = mbxs[mbx].front(); - - if (msg) { - *msg = thing; - } - - mbxs[mbx].pop(); - } - - return gotSomething ? KE_OK : KE_MBOX_NOMSG; - } - - s32 PeekMbx(s32 mbx) { return !mbxs[mbx].empty(); } - - /*! - * Push something into a mbx - */ - s32 SendMbx(s32 mbx, void* value) { - ASSERT(mbx < (s32)mbxs.size()); - mbxs[mbx].push(value); - return 0; - } - - s32 CreateSema(s32 attr, s32 option, s32 init_count, s32 max_count) { - s32 id = semas.size(); - semas.emplace_back((Semaphore::attribute)attr, option, init_count, max_count); - return id; - } + s32 CreateMbx(); + s32 ReceiveMbx(void** msg, s32 mbx); + s32 PollMbx(void** msg, s32 mbx); + s32 PeekMbx(s32 mbx); + s32 SendMbx(s32 mbx, void* value); + s32 CreateSema(s32 attr, s32 option, s32 init_count, s32 max_count); s32 WaitSema(s32 id); s32 SignalSema(s32 id); s32 PollSema(s32 id); @@ -205,7 +172,7 @@ class IOP_Kernel { s32 _nextThID = 0; IopThread* _currentThread = nullptr; std::vector threads; - std::vector> mbxs; + std::vector mbxs; std::vector sif_records; std::vector semas; std::queue wakeup_queue; From fdb439e014a83a8cec09bd0879761b3d4c15a727 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 2 May 2024 06:21:21 +0200 Subject: [PATCH 09/14] wip --- game/CMakeLists.txt | 1 + game/overlord/jak3/basefilesystem.h | 11 ++++++++-- game/overlord/jak3/iso.cpp | 23 +++++++++++++++++++++ game/overlord/jak3/iso.h | 11 ++++++++++ game/overlord/jak3/iso_api.cpp | 31 +++++++++++++++++++++++++++++ game/overlord/jak3/iso_api.h | 12 +++++++++++ game/overlord/jak3/iso_fake.cpp | 8 ++++---- game/overlord/jak3/iso_fake.h | 4 ++-- game/overlord/jak3/iso_structs.h | 10 +++++++++- 9 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 game/overlord/jak3/iso_api.cpp create mode 100644 game/overlord/jak3/iso_api.h diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index db544438747..820e87c6c8f 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -252,6 +252,7 @@ set(RUNTIME_SOURCE overlord/jak2/streamlist.cpp overlord/jak2/vag.cpp overlord/jak3/start.cpp + overlord/jak3/iso_api.cpp overlord/jak3/iso_fake.cpp overlord/jak3/iso.cpp overlord/jak3/overlord.cpp diff --git a/game/overlord/jak3/basefilesystem.h b/game/overlord/jak3/basefilesystem.h index 18100f66e08..f92162469ce 100644 --- a/game/overlord/jak3/basefilesystem.h +++ b/game/overlord/jak3/basefilesystem.h @@ -1,5 +1,6 @@ #pragma once +#include "game/overlord/jak3/basefile.h" #include "game/overlord/jak3/iso_structs.h" namespace jak3 { @@ -10,8 +11,14 @@ class CBaseFileSystem { virtual const ISOFileDef* Find(const char* name) = 0; virtual const ISOFileDef* FindIN(const char* name) = 0; virtual int GetLength(const ISOFileDef* def) = 0; - virtual int Open(const ISOFileDef* def, int offset, EFileComp mode) = 0; - virtual int OpenWad(const ISOFileDef* def, int offset) = 0; + virtual CBaseFile* Open(const ISOFileDef* def, int offset, EFileComp mode) = 0; + virtual CBaseFile* OpenWad(const ISOFileDef* def, int offset) = 0; virtual VagDirEntryJak3* FindVagFile(const char* name) = 0; + + u8* CheckForPageBoundaryCrossing(); + + private: + ISOBuffer m_Buffer; }; + } // namespace jak3 diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index bf8c1d50474..24ed83d2b26 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -6,6 +6,7 @@ #include "game/common/dgo_rpc_types.h" #include "game/overlord/jak3/basefilesystem.h" +#include "game/overlord/jak3/iso_api.h" #include "game/overlord/jak3/iso_fake.h" #include "game/overlord/jak3/stream.h" @@ -18,6 +19,7 @@ int g_nDGOThreadID; int g_nSTRThreadID; int g_nPlayThreadID; int g_nISOMbx; +VagDirJak3 g_VagDir; static int s_nISOInitFlag; static ISO_LoadDGO s_LoadDGO; @@ -58,13 +60,17 @@ static void WaitMbx(int mbx) { /* TODO unfinished */ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { + const ISOFileDef* fd; ThreadParam thp; MbxParam mbx; memset(&s_LoadDGO, 0, sizeof(s_LoadDGO)); + /* TODO INIT s_LoadDgo fields */ + s_nISOInitFlag = 1; g_pFileSystem = &g_FakeISOCDFileSystem; + /* Lets not bother error checking the Create* calls */ mbx.attr = 0; mbx.option = 0; g_nISOMbx = CreateMbx(&mbx); @@ -110,10 +116,27 @@ int InitISOFS(const char* fs_mode, const char* loading_sceeen) { StartThread(g_nSTRThreadID, 0); StartThread(g_nPlayThreadID, 0); + WaitMbx(s_nSyncMbx); + + /* Originally VAGDIR is only loaded for the CD filesystem + * Presumably there was different mechanism for fakeiso, + * but we need it regardless */ + + fd = FindIsoFile("VAGDIR.AYB"); + LoadISOFileToIOP(fd, &g_VagDir, sizeof(g_VagDir)); + + /* Skip getting the loading screen thing? */ + return s_nISOInitFlag; } +const ISOFileDef* FindIsoFile(const char* name) { + return g_pFileSystem->Find(name); +} + u32 ISOThread() { + InitDriver(); + while (true) { DelayThread(4000); } diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h index d8fd39abab7..440d197bb63 100644 --- a/game/overlord/jak3/iso.h +++ b/game/overlord/jak3/iso.h @@ -4,6 +4,7 @@ #include "game/sce/iop.h" namespace jak3 { +extern int g_nISOMbx; struct ISO_Hdr { iop::MsgPacket m_Pkt; @@ -29,5 +30,15 @@ struct ISO_LoadDGO : ISO_Msg { ISOFileDef* fd; }; +struct ISO_LoadSingle : ISO_Msg { + const ISOFileDef* fd; + void* address; + u32 length; + u32 length_to_copy; + u32 offset; +}; + int InitISOFS(const char* fs_mode, const char* loading_sceeen); +const ISOFileDef* FindIsoFile(const char* name); + } // namespace jak3 diff --git a/game/overlord/jak3/iso_api.cpp b/game/overlord/jak3/iso_api.cpp new file mode 100644 index 00000000000..9ffd12607a6 --- /dev/null +++ b/game/overlord/jak3/iso_api.cpp @@ -0,0 +1,31 @@ +#include "iso_api.h" + +#include "common/common_types.h" + +#include "game/overlord/jak3/iso.h" +#include "game/overlord/jak3/iso_structs.h" + +namespace jak3 { +using namespace iop; + +u32 LoadISOFileToIOP(const ISOFileDef* file, void* addr, u32 length) { + ISO_LoadSingle msg; + + msg.cmd_kind = 0x101; + msg.mbx_to_reply = 0; + msg.thread_id = GetThreadId(); + msg.fd = file; + msg.address = addr; + msg.length = length; + SendMbx(g_nISOMbx, &msg); + SleepThread(); + + u32 ret = 0; + if (msg.m_nStatus == 0) { + ret = msg.length_to_copy; + } + + return ret; +} + +} // namespace jak3 diff --git a/game/overlord/jak3/iso_api.h b/game/overlord/jak3/iso_api.h new file mode 100644 index 00000000000..6866a997edb --- /dev/null +++ b/game/overlord/jak3/iso_api.h @@ -0,0 +1,12 @@ +#ifndef ISO_API_H_ +#define ISO_API_H_ + +#include "common/common_types.h" + +#include "game/overlord/jak3/iso_structs.h" + +namespace jak3 { +u32 LoadISOFileToIOP(const ISOFileDef* file, void* addr, u32 length); +} + +#endif // ISO_API_H_ diff --git a/game/overlord/jak3/iso_fake.cpp b/game/overlord/jak3/iso_fake.cpp index 23ba9a246bc..a906a5a7114 100644 --- a/game/overlord/jak3/iso_fake.cpp +++ b/game/overlord/jak3/iso_fake.cpp @@ -21,12 +21,12 @@ int CFakeISOCDFileSystem::GetLength(const ISOFileDef* def) { return 0; } -int CFakeISOCDFileSystem::Open(const ISOFileDef* def, int offset, EFileComp mode) { - return 0; +CBaseFile* CFakeISOCDFileSystem::Open(const ISOFileDef* def, int offset, EFileComp mode) { + return nullptr; } -int CFakeISOCDFileSystem::OpenWad(const ISOFileDef* def, int offset) { - return 0; +CBaseFile* CFakeISOCDFileSystem::OpenWad(const ISOFileDef* def, int offset) { + return nullptr; } VagDirEntryJak3* CFakeISOCDFileSystem::FindVagFile(const char* name) { diff --git a/game/overlord/jak3/iso_fake.h b/game/overlord/jak3/iso_fake.h index b73d3aac934..16bbb7b8693 100644 --- a/game/overlord/jak3/iso_fake.h +++ b/game/overlord/jak3/iso_fake.h @@ -13,8 +13,8 @@ class CFakeISOCDFileSystem : public CBaseFileSystem { const ISOFileDef* Find(const char* name) override; const ISOFileDef* FindIN(const char* name) override; int GetLength(const ISOFileDef* def) override; - int Open(const ISOFileDef* def, int offset, EFileComp mode) override; - int OpenWad(const ISOFileDef* def, int offset) override; + CBaseFile* Open(const ISOFileDef* def, int offset, EFileComp mode) override; + CBaseFile* OpenWad(const ISOFileDef* def, int offset) override; VagDirEntryJak3* FindVagFile(const char* name) override; }; diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index 2c66fdcaea6..ac55a5c7672 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -2,11 +2,17 @@ #include "common/common_types.h" +#include "game/overlord/jak3/pagemanager.h" + namespace jak3 { /* TODO check values */ enum class EFileComp { MODE0, MODE1, KNOWN_NOT_BLZO }; struct ISOBuffer { + CPageManager::CPageList* m_pActivePages; + void* decomp_buffer; + int decompressed_size; + void AdjustDataLength(int); void AdvanceCurrentData(int); }; @@ -24,11 +30,13 @@ struct VagDirEntryJak3 { }; }; +static constexpr int MAX_VAGDIR_ENTRIES = 4096; + struct VagDirJak3 { u32 id[2]; u32 version; u32 count; - VagDirEntryJak3 entries[0]; + VagDirEntryJak3 entries[MAX_VAGDIR_ENTRIES]; }; struct VagDirEntry {}; From 1c034c97bf9c73fa7224d0989d014637d58f4a96 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 2 May 2024 06:48:56 +0200 Subject: [PATCH 10/14] Add no-op Suspend/Resume intr --- game/sce/iop.cpp | 10 ++++++++++ game/sce/iop.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/game/sce/iop.cpp b/game/sce/iop.cpp index feeafe90ea2..b40bdf3cf96 100644 --- a/game/sce/iop.cpp +++ b/game/sce/iop.cpp @@ -251,4 +251,14 @@ s32 RegisterVblankHandler(int edge, int priority, int (*handler)(void*), void* / return iop->kernel.RegisterVblankHandler(handler); } +s32 CpuSuspendIntr(int* old_state) { + (void)old_state; + return KE_OK; +} + +s32 CpuResumeIntr(int old_state) { + (void)old_state; + return KE_OK; +} + } // namespace iop diff --git a/game/sce/iop.h b/game/sce/iop.h index 216faee08fd..306bc340893 100644 --- a/game/sce/iop.h +++ b/game/sce/iop.h @@ -159,6 +159,9 @@ void FlushDcache(); u32 sceSifCheckInit(); void sceSifInit(); +s32 CpuSuspendIntr(int* old_state); +s32 CpuResumeIntr(int old_state); + void LIBRARY_INIT(); void LIBRARY_register(::IOP* i); void LIBRARY_kill(); From b5b45b2c9910d1e7f7e45ce620721f30f5e956ba Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 2 May 2024 07:45:15 +0200 Subject: [PATCH 11/14] wip --- game/CMakeLists.txt | 1 + game/overlord/jak3/iso.cpp | 64 ++++++++++++++++++++++++++++++ game/overlord/jak3/iso.h | 10 ++--- game/overlord/jak3/iso_api.cpp | 2 +- game/overlord/jak3/iso_queue.cpp | 35 ++++++++++++++++ game/overlord/jak3/iso_queue.h | 8 ++++ game/overlord/jak3/iso_structs.h | 2 +- game/overlord/jak3/pagemanager.cpp | 53 +++++++++++++++++++++++++ game/overlord/jak3/pagemanager.h | 26 ++++++++++++ 9 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 game/overlord/jak3/iso_queue.cpp create mode 100644 game/overlord/jak3/iso_queue.h diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 820e87c6c8f..0a428a460d9 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -254,6 +254,7 @@ set(RUNTIME_SOURCE overlord/jak3/start.cpp overlord/jak3/iso_api.cpp overlord/jak3/iso_fake.cpp + overlord/jak3/iso_queue.cpp overlord/jak3/iso.cpp overlord/jak3/overlord.cpp overlord/jak3/pagemanager.cpp diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index 24ed83d2b26..e7ec44cd2f2 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -5,9 +5,11 @@ #include "common/log/log.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" +#include "game/overlord/jak3/iso_queue.h" #include "game/overlord/jak3/stream.h" namespace jak3 { @@ -20,6 +22,8 @@ int g_nSTRThreadID; int g_nPlayThreadID; int g_nISOMbx; VagDirJak3 g_VagDir; +char g_szCurrentMusicName[16]; +char g_szTargetMusicName[16]; static int s_nISOInitFlag; static ISO_LoadDGO s_LoadDGO; @@ -30,6 +34,7 @@ static int s_nDGOMbx; static u32 DGOThread(); u32 ISOThread(); +int NullCallback(ISO_Msg* msg); /* COMPLETE */ void InitDriver() { @@ -135,9 +140,35 @@ const ISOFileDef* FindIsoFile(const char* name) { } u32 ISOThread() { + ISO_Msg* msg; + + g_szCurrentMusicName[0] = '\0'; + g_szTargetMusicName[0] = '\0'; + InitBuffers(); + // InitVagCmds(); + InitDriver(); while (true) { + int res = PollMbx((MsgPacket**)&msg, g_nISOMbx); + if (res == KE_OK) { + msg->SetActive(false); + msg->SetUnk1(false); + msg->SetUnk2(false); + msg->file = nullptr; + msg->callback = NullCallback; + + switch (msg->msg_kind) { + case LOAD_TO_EE_CMD_ID: + case LOAD_TO_IOP_CMD_ID: + case LOAD_TO_EE_OFFSET_CMD_ID: + break; + default: + lg::error("unhandled iso msg type {:x}", msg->msg_kind); + break; + } + } + DelayThread(4000); } @@ -208,4 +239,37 @@ s32 GetISOFileLength(const ISOFileDef* fd) { return g_pFileSystem->GetLength(fd); } +int NullCallback(ISO_Msg* msg) { + return 7; +} + +void ISO_Hdr::SetActive(bool b) { + m_bActive = b; +} + +void ISO_Hdr::SetUnk1(bool b) { + unk1 = b; +} + +void ISO_Hdr::SetUnk2(bool b) { + unk2 = b; +} + +void ISOBuffer::AdjustDataLength(int size) { + int state; + + CpuSuspendIntr(&state); + decompressed_size -= size; + CpuResumeIntr(state); +} + +void ISOBuffer::AdvanceCurrentData(int size) { + int state; + + CpuSuspendIntr(&state); + decomp_buffer += size; + decompressed_size -= size; + CpuResumeIntr(state); +} + } // namespace jak3 diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h index 440d197bb63..2ddf613f7b3 100644 --- a/game/overlord/jak3/iso.h +++ b/game/overlord/jak3/iso.h @@ -13,16 +13,16 @@ struct ISO_Hdr { bool unk1; bool unk2; - void SetActive(); - void SetUnk1(); - void SetUnk2(); + void SetActive(bool b); + void SetUnk1(bool b); + void SetUnk2(bool b); }; struct ISO_Msg : ISO_Hdr { - u32 cmd_kind; + u32 msg_kind; int mbx_to_reply; int thread_id; - void* callback; + int (*callback)(ISO_Msg*); CBaseFile* file; }; diff --git a/game/overlord/jak3/iso_api.cpp b/game/overlord/jak3/iso_api.cpp index 9ffd12607a6..1b083dd4425 100644 --- a/game/overlord/jak3/iso_api.cpp +++ b/game/overlord/jak3/iso_api.cpp @@ -11,7 +11,7 @@ using namespace iop; u32 LoadISOFileToIOP(const ISOFileDef* file, void* addr, u32 length) { ISO_LoadSingle msg; - msg.cmd_kind = 0x101; + msg.msg_kind = 0x101; msg.mbx_to_reply = 0; msg.thread_id = GetThreadId(); msg.fd = file; diff --git a/game/overlord/jak3/iso_queue.cpp b/game/overlord/jak3/iso_queue.cpp new file mode 100644 index 00000000000..dc457a0212d --- /dev/null +++ b/game/overlord/jak3/iso_queue.cpp @@ -0,0 +1,35 @@ +#include "iso_queue.h" + +#include "game/overlord/jak3/pagemanager.h" +#include "game/sce/iop.h" + +namespace jak3 { +using namespace iop; + +constexpr int N_VAG_CMDS = 6; + +u32 g_auStreamSRAM[N_VAG_CMDS]; +u32 g_auTrapSRAM[N_VAG_CMDS]; +int g_nPriQueueSema; +int g_nISOSema; + +CPageManager g_PageManager; + +void InitBuffers() { + SemaParam semap; + + semap.init_count = 1; + semap.max_count = 1; + semap.attr = 0; + semap.option = 0; + g_nPriQueueSema = CreateSema(&semap); + + g_PageManager.Initialize(); + + semap.init_count = 1; + semap.max_count = 1; + semap.attr = SA_THPRI; + semap.option = 0; + g_nISOSema = CreateSema(&semap); +} +} // namespace jak3 diff --git a/game/overlord/jak3/iso_queue.h b/game/overlord/jak3/iso_queue.h new file mode 100644 index 00000000000..2433d56a32a --- /dev/null +++ b/game/overlord/jak3/iso_queue.h @@ -0,0 +1,8 @@ +#ifndef ISO_QUEUE_H_ +#define ISO_QUEUE_H_ + +namespace jak3 { +void InitBuffers(); +} + +#endif // ISO_QUEUE_H_ diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index ac55a5c7672..66d4f42e211 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -10,7 +10,7 @@ enum class EFileComp { MODE0, MODE1, KNOWN_NOT_BLZO }; struct ISOBuffer { CPageManager::CPageList* m_pActivePages; - void* decomp_buffer; + u8* decomp_buffer; int decompressed_size; void AdjustDataLength(int); diff --git a/game/overlord/jak3/pagemanager.cpp b/game/overlord/jak3/pagemanager.cpp index c6be36f641e..dc310dfc3cb 100644 --- a/game/overlord/jak3/pagemanager.cpp +++ b/game/overlord/jak3/pagemanager.cpp @@ -1,6 +1,12 @@ #include "pagemanager.h" +#include "game/sce/iop.h" + namespace jak3 { +using namespace iop; + +static constexpr u32 PAGE_SIZE = 0x8010; +static constexpr u32 NUM_PAGES = 29; static inline int ctz(u32 x) { // Isolate lowest bit and subtract 1 @@ -17,4 +23,51 @@ static inline int ctz(u32 x) { return static_cast(x); } +CPageManager::CPage::CPage(u8* start, u8* end, int page_id) { + m_pNextPage = nullptr; + m_uPageBit = 1 << (page_id & 0x1f); + m_nUnk = 0; + m_pData = start; + m_pEnd = end; + m_nRefCount = 0; + m_nPageID = page_id; + m_nDmaRefCount = 0; + m_nAllocState = 0; + m_nUnk2 = 0; +} + +void CPageManager::Initialize() { + m_Cache.Initialize(); +} + +CPageManager::CCache::CCache() { + m_paCache = nullptr; + m_uAllocatedPageMap = 0; + m_uFreePageMap = (1 << NUM_PAGES) - 1; +} + +int CPageManager::CCache::Initialize() { + m_paCache = AllocSysMemory(0, PAGE_SIZE * NUM_PAGES, nullptr); + if (!m_paCache) { + return 1; + } + + m_nNumFree = 29; + + /* TODO FIXME */ + for (auto& pl : m_aPageLists) { + } + + int page_idx = 0; + u8* page_start = (u8*)m_paCache; + for (auto& page : m_aPages) { + page = CPage(page_start, page_start + 0x7fff, page_idx); + + page_start += PAGE_SIZE; + page_idx++; + } + + return 0; +} + } // namespace jak3 diff --git a/game/overlord/jak3/pagemanager.h b/game/overlord/jak3/pagemanager.h index 8ac7cc5a2df..df49b57b04b 100644 --- a/game/overlord/jak3/pagemanager.h +++ b/game/overlord/jak3/pagemanager.h @@ -5,14 +5,30 @@ namespace jak3 { class CPageManager { public: + class CPageList; + class CPage { public: + CPage() = default; CPage(u8*, u8*, int); int AddRef(); int ReleaseRef(); int AddDmaRef(); int ReleaseDmaRef(); void FromPagesCopy(u8* pInPageData, u8* pDest, int nNumBytes); + + private: + CPage* m_pNextPage; + u32 m_uPageBit; + u32 m_nUnk; + CPageList* m_pPageList; + u8* m_pData; + u8* m_pEnd; // maybe + u32 m_nRefCount; + u32 m_nDmaRefCount; + int m_nPageID; + int m_nAllocState; + int m_nUnk2; }; class CPageList { @@ -33,7 +49,17 @@ class CPageManager { private: class CCache { public: + CCache(); int Initialize(); + + private: + int m_nEventFlag; + void* m_paCache; + CPageList m_aPageLists[29]; + CPage m_aPages[29]; + u32 m_uAllocatedPageMap; + u32 m_uFreePageMap; + int m_nNumFree; }; CCache m_Cache; }; From 78917bd96e24f2fd0f323a1be02bcb01d9da514d Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 2 May 2024 13:24:58 +0200 Subject: [PATCH 12/14] wip --- game/overlord/jak3/pagemanager.cpp | 71 ++++++++++++++++++++++++++++++ game/overlord/jak3/pagemanager.h | 11 ++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/game/overlord/jak3/pagemanager.cpp b/game/overlord/jak3/pagemanager.cpp index dc310dfc3cb..866bb34931d 100644 --- a/game/overlord/jak3/pagemanager.cpp +++ b/game/overlord/jak3/pagemanager.cpp @@ -36,6 +36,77 @@ CPageManager::CPage::CPage(u8* start, u8* end, int page_id) { m_nUnk2 = 0; } +int CPageManager::CPage::AddRef() { + int state, ret = -1; + + CpuSuspendIntr(&state); + + if (m_nAllocState == 1 && m_pPageList != nullptr) { + m_pPageList->m_nRefCount++; + m_nRefCount++; + ret = m_nRefCount; + } + + CpuResumeIntr(state); + + return ret; +} + +int CPageManager::CPage::ReleaseRef() { + int state, ret = -1; + + CpuSuspendIntr(&state); + + if (m_nAllocState == 1 && m_pPageList != nullptr) { + m_pPageList->m_nRefCount--; + m_nRefCount--; + ret = m_nRefCount; + } + + CpuResumeIntr(state); + + return ret; +} + +int CPageManager::CPage::AddDmaRef() { + int state, ret = -1; + + CpuSuspendIntr(&state); + + if (m_nAllocState == 1 && m_pPageList != nullptr) { + m_pPageList->m_nDmaRefCount++; + m_nDmaRefCount++; + ret = m_nDmaRefCount; + } + + CpuResumeIntr(state); + + return ret; +} + +int CPageManager::CPage::ReleaseDmaRef() { + int state, ret = -1; + + CpuSuspendIntr(&state); + + if (m_nAllocState == 1 && m_pPageList != nullptr) { + m_pPageList->m_nDmaRefCount--; + m_nDmaRefCount--; + ret = m_nDmaRefCount; + } + + CpuResumeIntr(state); + + return ret; +} + +void CPageManager::CPage::FromPagesCopy(u8* pInPageData, u8* pDest, int nNumBytes) { + if (nNumBytes <= 0) { + return; + } + +} + void CPageManager::Initialize() { m_Cache.Initialize(); } diff --git a/game/overlord/jak3/pagemanager.h b/game/overlord/jak3/pagemanager.h index df49b57b04b..757bb01be18 100644 --- a/game/overlord/jak3/pagemanager.h +++ b/game/overlord/jak3/pagemanager.h @@ -24,18 +24,25 @@ class CPageManager { CPageList* m_pPageList; u8* m_pData; u8* m_pEnd; // maybe - u32 m_nRefCount; - u32 m_nDmaRefCount; + int m_nRefCount; + int m_nDmaRefCount; int m_nPageID; int m_nAllocState; int m_nUnk2; }; class CPageList { + friend class CPage; + + public: int AddActivePages(int); int CancelActivePages(); CPage* StepActivePage(); void GarbageCollect(); + + private: + int m_nRefCount; + int m_nDmaRefCount; }; void Initialize(); From 6628fc36004eec115b180eff72cbb84f866c76da Mon Sep 17 00:00:00 2001 From: Ziemas Date: Fri, 3 May 2024 15:13:09 +0200 Subject: [PATCH 13/14] pagemanager: mostly map out structs --- game/overlord/jak3/iso_structs.h | 11 +++- game/overlord/jak3/pagemanager.cpp | 88 +++++++++++++++++------------- game/overlord/jak3/pagemanager.h | 58 +++++++++++++++----- 3 files changed, 103 insertions(+), 54 deletions(-) diff --git a/game/overlord/jak3/iso_structs.h b/game/overlord/jak3/iso_structs.h index 66d4f42e211..b69ca409ec4 100644 --- a/game/overlord/jak3/iso_structs.h +++ b/game/overlord/jak3/iso_structs.h @@ -9,12 +9,17 @@ namespace jak3 { enum class EFileComp { MODE0, MODE1, KNOWN_NOT_BLZO }; struct ISOBuffer { + public: + void AdjustDataLength(int); + void AdvanceCurrentData(int); + void SetDataLength(int length) { m_nDataLength = length; } + int GetDataLength() { return m_nDataLength; } + + private: CPageManager::CPageList* m_pActivePages; u8* decomp_buffer; int decompressed_size; - - void AdjustDataLength(int); - void AdvanceCurrentData(int); + int m_nDataLength; }; struct VagDirEntryJak3 { diff --git a/game/overlord/jak3/pagemanager.cpp b/game/overlord/jak3/pagemanager.cpp index 866bb34931d..6e33840288c 100644 --- a/game/overlord/jak3/pagemanager.cpp +++ b/game/overlord/jak3/pagemanager.cpp @@ -1,5 +1,9 @@ #include "pagemanager.h" +#include + +#include "common/util/Assert.h" + #include "game/sce/iop.h" namespace jak3 { @@ -8,32 +12,17 @@ using namespace iop; static constexpr u32 PAGE_SIZE = 0x8010; static constexpr u32 NUM_PAGES = 29; -static inline int ctz(u32 x) { - // Isolate lowest bit and subtract 1 - x = (x & -x) - 1; - - // popcount - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += (x >> 8); - x += (x >> 16); - x &= 0x3f; - - return static_cast(x); -} - CPageManager::CPage::CPage(u8* start, u8* end, int page_id) { m_pNextPage = nullptr; m_uPageBit = 1 << (page_id & 0x1f); - m_nUnk = 0; + m_nPageState = 0; m_pData = start; - m_pEnd = end; - m_nRefCount = 0; + m_pDataEnd = end; + m_nPageRefCount = 0; m_nPageID = page_id; - m_nDmaRefCount = 0; + m_nPageDmaRefCount = 0; m_nAllocState = 0; - m_nUnk2 = 0; + m_nPageState = 0; } int CPageManager::CPage::AddRef() { @@ -42,9 +31,9 @@ int CPageManager::CPage::AddRef() { CpuSuspendIntr(&state); if (m_nAllocState == 1 && m_pPageList != nullptr) { - m_pPageList->m_nRefCount++; - m_nRefCount++; - ret = m_nRefCount; + m_pPageList->m_nListRefCount++; + m_nPageRefCount++; + ret = m_nPageRefCount; } CpuResumeIntr(state); @@ -58,9 +47,9 @@ int CPageManager::CPage::ReleaseRef() { CpuSuspendIntr(&state); if (m_nAllocState == 1 && m_pPageList != nullptr) { - m_pPageList->m_nRefCount--; - m_nRefCount--; - ret = m_nRefCount; + m_pPageList->m_nListRefCount--; + m_nPageRefCount--; + ret = m_nPageRefCount; } CpuResumeIntr(state); @@ -74,9 +63,9 @@ int CPageManager::CPage::AddDmaRef() { CpuSuspendIntr(&state); if (m_nAllocState == 1 && m_pPageList != nullptr) { - m_pPageList->m_nDmaRefCount++; - m_nDmaRefCount++; - ret = m_nDmaRefCount; + m_pPageList->m_nListDmaRefCount++; + m_nPageDmaRefCount++; + ret = m_nPageDmaRefCount; } CpuResumeIntr(state); @@ -90,9 +79,9 @@ int CPageManager::CPage::ReleaseDmaRef() { CpuSuspendIntr(&state); if (m_nAllocState == 1 && m_pPageList != nullptr) { - m_pPageList->m_nDmaRefCount--; - m_nDmaRefCount--; - ret = m_nDmaRefCount; + m_pPageList->m_nListDmaRefCount--; + m_nPageDmaRefCount--; + ret = m_nPageDmaRefCount; } CpuResumeIntr(state); @@ -101,20 +90,37 @@ int CPageManager::CPage::ReleaseDmaRef() { } void CPageManager::CPage::FromPagesCopy(u8* pInPageData, u8* pDest, int nNumBytes) { + int nInputPageLengthLeft; + CPage* page = this; + if (nNumBytes <= 0) { return; } -} + for (;;) { + nInputPageLengthLeft = (uintptr_t)page->m_pDataEnd + (1 - (uintptr_t)pInPageData); + if (nInputPageLengthLeft <= nNumBytes) { + break; + } -void CPageManager::Initialize() { - m_Cache.Initialize(); + if (nNumBytes <= 0) { + nNumBytes -= nInputPageLengthLeft; + return; + } + + ASSERT(m_pNextPage != nullptr); + + page = page->m_pNextPage; + pInPageData = page->m_pData; + } + + memcpy(pDest, pInPageData, nNumBytes); } CPageManager::CCache::CCache() { m_paCache = nullptr; m_uAllocatedPageMap = 0; - m_uFreePageMap = (1 << NUM_PAGES) - 1; + m_Unk = (1 << NUM_PAGES) - 1; } int CPageManager::CCache::Initialize() { @@ -125,8 +131,8 @@ int CPageManager::CCache::Initialize() { m_nNumFree = 29; - /* TODO FIXME */ for (auto& pl : m_aPageLists) { + pl = {}; } int page_idx = 0; @@ -141,4 +147,12 @@ int CPageManager::CCache::Initialize() { return 0; } +void CPageManager::Initialize() { + m_Cache.Initialize(); +} + +int CPageManager::TryFreePages(int nPages) { + return 0; +} + } // namespace jak3 diff --git a/game/overlord/jak3/pagemanager.h b/game/overlord/jak3/pagemanager.h index 757bb01be18..435d6118285 100644 --- a/game/overlord/jak3/pagemanager.h +++ b/game/overlord/jak3/pagemanager.h @@ -7,6 +7,11 @@ class CPageManager { public: class CPageList; + enum class AllocState { + EPLAS_FREE, + EPLAS_ALLOCATED, + }; + class CPage { public: CPage() = default; @@ -16,19 +21,28 @@ class CPageManager { int AddDmaRef(); int ReleaseDmaRef(); void FromPagesCopy(u8* pInPageData, u8* pDest, int nNumBytes); + u8* GetStart() const; + u8* GetEnd() const; + bool IsReferenced() { return m_nPageRefCount != 0 || m_nPageDmaRefCount != 0; } + bool IsFilled() const; // Exists as string in july version, not sure on impl + bool IsAllocated() const; + void SetPageInputState(int state); // enum + int GetPageCacheIndex() const; + CPage* GetNextPage() const; + CPage* GetPrevPage() const; private: CPage* m_pNextPage; - u32 m_uPageBit; - u32 m_nUnk; + CPage* m_pPrevPage; CPageList* m_pPageList; + int m_nPageRefCount; + int m_nPageDmaRefCount; + int m_nAllocState; + u32 m_nPageState; // 3: filled otherwise unk? u8* m_pData; - u8* m_pEnd; // maybe - int m_nRefCount; - int m_nDmaRefCount; + u8* m_pDataEnd; int m_nPageID; - int m_nAllocState; - int m_nUnk2; + u32 m_uPageBit; }; class CPageList { @@ -39,10 +53,25 @@ class CPageManager { int CancelActivePages(); CPage* StepActivePage(); void GarbageCollect(); + CPage* GetCurrentActivePage() const; + int GetNumRawPages() const; + int GetFirstRawPage() const; + int GetNumUnsteppedPages() const; + bool IsReferenced() { return m_nListRefCount != 0 || m_nListDmaRefCount != 0; } + int GetNumActivePages() const; private: - int m_nRefCount; - int m_nDmaRefCount; + CPage* m_pFirstPage; + CPage* m_pLastPage; + CPage* m_pFirstACtivePage; + CPage* m_pLastActivePage; + CPage* m_pCurrentActivePage; + int m_nNumPages; + int m_nNumActivePages; + int m_nNumUnsteppedPages; + int m_nListRefCount; + int m_nListDmaRefCount; + int m_nAllocState; }; void Initialize(); @@ -50,7 +79,7 @@ class CPageManager { CPageList* AllocPageList(int nPages, char unk); CPageList* GrowPageList(CPageList* list, char nPages); int FreePageList(CPageList* list); - int Unk(int nUnk); + int TryFreePages(int nUnk); void GarbageCollect(); private: @@ -59,15 +88,16 @@ class CPageManager { CCache(); int Initialize(); - private: - int m_nEventFlag; void* m_paCache; CPageList m_aPageLists[29]; CPage m_aPages[29]; - u32 m_uAllocatedPageMap; - u32 m_uFreePageMap; int m_nNumFree; + u32 m_uAllocatedPageMap; + u32 m_uAllocatedListMap; + int m_nEventFlag; + u32 m_Unk; }; + CCache m_Cache; }; From d114ca830947d53a7ad40705560d35f007ce7791 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 12 May 2024 19:58:31 +0200 Subject: [PATCH 14/14] queue load single messages --- game/overlord/jak3/iso.cpp | 113 ++++++++++++++++++++++++++--- game/overlord/jak3/iso.h | 17 ++++- game/overlord/jak3/iso_queue.cpp | 43 +++++++++++ game/overlord/jak3/iso_queue.h | 15 +++- game/overlord/jak3/pagemanager.cpp | 33 +++++++++ 5 files changed, 208 insertions(+), 13 deletions(-) diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index e7ec44cd2f2..265ef9aeb8f 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -3,9 +3,9 @@ #include #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; - switch (msg->msg_kind) { - case LOAD_TO_EE_CMD_ID: - case LOAD_TO_IOP_CMD_ID: - case LOAD_TO_EE_OFFSET_CMD_ID: + /* LoadSingle messages */ + if (msg->msg_kind >= LOAD_TO_EE_CMD_ID && msg->msg_kind <= LOAD_TO_989SND) { + auto* ls = static_cast(msg); + int pri = 0; + if (ls->unk40 == 2) { + pri = 2; + } + if (ls->unk40 == 10) { + pri = 4; + } + if (!QueueMessage(msg, pri)) { break; - default: - lg::error("unhandled iso msg type {:x}", msg->msg_kind); + } + + 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: + 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; } diff --git a/game/overlord/jak3/iso.h b/game/overlord/jak3/iso.h index 2ddf613f7b3..9d7f5b69ab0 100644 --- a/game/overlord/jak3/iso.h +++ b/game/overlord/jak3/iso.h @@ -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); diff --git a/game/overlord/jak3/iso_queue.cpp b/game/overlord/jak3/iso_queue.cpp index dc457a0212d..92561d525f3 100644 --- a/game/overlord/jak3/iso_queue.cpp +++ b/game/overlord/jak3/iso_queue.cpp @@ -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 diff --git a/game/overlord/jak3/iso_queue.h b/game/overlord/jak3/iso_queue.h index 2433d56a32a..156d265719e 100644 --- a/game/overlord/jak3/iso_queue.h +++ b/game/overlord/jak3/iso_queue.h @@ -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_ diff --git a/game/overlord/jak3/pagemanager.cpp b/game/overlord/jak3/pagemanager.cpp index 6e33840288c..f4a82e9d693 100644 --- a/game/overlord/jak3/pagemanager.cpp +++ b/game/overlord/jak3/pagemanager.cpp @@ -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