2024-02-17 01:04:22 +03:00
|
|
|
#include "sys.h"
|
2024-04-05 23:11:36 +03:00
|
|
|
#include "sf64audio_external.h"
|
2023-10-07 09:29:38 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
s32 sGammaMode = 1;
|
2024-02-17 01:04:22 +03:00
|
|
|
|
2023-11-13 01:49:03 +03:00
|
|
|
SPTask* gCurrentTask;
|
2023-11-24 22:11:20 +03:00
|
|
|
SPTask* sAudioTasks[1];
|
|
|
|
SPTask* sGfxTasks[2];
|
|
|
|
SPTask* sNewAudioTasks[1];
|
|
|
|
SPTask* sNewGfxTasks[2];
|
2023-11-13 01:49:03 +03:00
|
|
|
u32 gSegments[16]; // 800E1FD0
|
|
|
|
OSMesgQueue gPiMgrCmdQueue; // 800E2010
|
|
|
|
OSMesg sPiMgrCmdBuff[50]; // 800E2028
|
|
|
|
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gDmaMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sDmaMsgBuff[1];
|
|
|
|
OSIoMesg gDmaIOMsg;
|
2023-11-13 01:49:03 +03:00
|
|
|
OSMesgQueue gSerialEventQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sSerialEventBuff[1];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gMainThreadMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sMainThreadMsgBuff[32];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gTaskMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sTaskMsgBuff[16];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gAudioVImesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sAudioVImsgBuff[1];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gAudioTaskMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sAudioTaskMsgBuff[1];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gGfxVImesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sGfxVImsgBuff[4];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gGfxTaskMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sGfxTaskMsgBuff[2];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gSerialThreadMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sSerialThreadMsgBuff[8];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gControllerMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sControllerMsgBuff[1];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gSaveMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sSaveMsgBuff[1];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gTimerTaskMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sTimerTaskMsgBuff[16];
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesgQueue gTimerWaitMesgQueue;
|
2023-11-24 22:11:20 +03:00
|
|
|
void* sTimerWaitMsgBuff[1];
|
2023-11-13 01:49:03 +03:00
|
|
|
|
|
|
|
GfxPool gGfxPools[2];
|
|
|
|
|
|
|
|
GfxPool* gGfxPool;
|
|
|
|
SPTask* gGfxTask;
|
|
|
|
Vp* gViewport;
|
|
|
|
Mtx* gGfxMtx;
|
|
|
|
Gfx* gUnkDisp1;
|
|
|
|
Gfx* gMasterDisp;
|
|
|
|
Gfx* gUnkDisp2;
|
|
|
|
Lightsn* gLight;
|
|
|
|
FrameBuffer* gFrameBuffer;
|
2023-12-15 23:09:49 +03:00
|
|
|
u16* gTextureRender;
|
2023-11-13 01:49:03 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
u8 gVIsPerFrame;
|
2024-01-17 18:36:58 +03:00
|
|
|
u32 gSysFrameCount;
|
2023-11-24 22:11:20 +03:00
|
|
|
u8 gStartNMI;
|
|
|
|
u8 gStopTasks;
|
2024-04-11 19:55:32 +03:00
|
|
|
u8 gControllerRumbleFlags[4];
|
2023-11-24 22:11:20 +03:00
|
|
|
u16 gFillScreenColor;
|
|
|
|
u16 gFillScreen;
|
2023-11-13 01:49:03 +03:00
|
|
|
|
|
|
|
u8 gUnusedStack[0x1000];
|
2023-11-28 23:03:47 +03:00
|
|
|
OSThread sIdleThread; // 80138E90
|
|
|
|
u8 sIdleThreadStack[0x1000]; // 801390A0
|
|
|
|
OSThread gMainThread; // 8013A040
|
|
|
|
u8 sMainThreadStack[0x1000]; // 8013A1F0
|
|
|
|
OSThread gAudioThread; // 8013B1F0
|
|
|
|
u8 gAudioThreadStack[0x1000]; // 800DDAA0
|
|
|
|
OSThread gGraphicsThread; // 800DEAA0
|
|
|
|
u8 gGraphicsThreadStack[0x1000]; // 800DEC50
|
|
|
|
OSThread gTimerThread; // 800DFC50
|
|
|
|
u8 gTimerThreadStack[0x1000]; // 800DFE00
|
|
|
|
OSThread gSerialThread; // 800E0E00
|
|
|
|
u8 gSerialThreadStack[0x1000]; // 800E0FB0
|
2023-11-13 01:49:03 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_Initialize(void) {
|
2023-11-08 01:32:09 +03:00
|
|
|
u8 i;
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
gVIsPerFrame = 0;
|
2024-01-17 18:36:58 +03:00
|
|
|
gSysFrameCount = 0;
|
2023-11-24 22:11:20 +03:00
|
|
|
gStartNMI = false;
|
|
|
|
gStopTasks = false;
|
|
|
|
gFillScreenColor = 0;
|
|
|
|
gFillScreen = false;
|
2023-11-08 01:32:09 +03:00
|
|
|
gCurrentTask = NULL;
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sAudioTasks); i += 1) {
|
|
|
|
sAudioTasks[i] = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sGfxTasks); i += 1) {
|
|
|
|
sGfxTasks[i] = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sNewAudioTasks); i += 1) {
|
|
|
|
sNewAudioTasks[i] = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sNewGfxTasks); i += 1) {
|
|
|
|
sNewGfxTasks[i] = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Audio_ThreadEntry(void* arg0) {
|
2023-11-13 01:49:03 +03:00
|
|
|
SPTask* task;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2024-02-24 04:56:08 +03:00
|
|
|
AudioLoad_Init();
|
2024-03-01 21:57:44 +03:00
|
|
|
Audio_InitSounds();
|
2024-03-06 01:51:52 +03:00
|
|
|
task = AudioThread_CreateTask();
|
2023-11-13 01:49:03 +03:00
|
|
|
if (task != NULL) {
|
2024-04-25 07:14:49 +03:00
|
|
|
task->mesgQueue = &gAudioTaskMesgQueue;
|
2023-11-13 01:49:03 +03:00
|
|
|
task->msg = (OSMesg) TASK_MESG_1;
|
2023-11-08 01:32:09 +03:00
|
|
|
osWritebackDCacheAll();
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gTaskMesgQueue, task, OS_MESG_NOBLOCK);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
while (1) {
|
2024-03-06 01:51:52 +03:00
|
|
|
task = AudioThread_CreateTask();
|
2023-11-13 01:49:03 +03:00
|
|
|
if (task != NULL) {
|
2024-04-25 07:14:49 +03:00
|
|
|
task->mesgQueue = &gAudioTaskMesgQueue;
|
2023-11-13 01:49:03 +03:00
|
|
|
task->msg = (OSMesg) TASK_MESG_1;
|
2023-11-08 01:32:09 +03:00
|
|
|
osWritebackDCacheAll();
|
|
|
|
}
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_GET_MESG(&gAudioTaskMesgQueue, NULL);
|
2023-11-13 01:49:03 +03:00
|
|
|
if (task != NULL) {
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gTaskMesgQueue, task, OS_MESG_NOBLOCK);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gAudioVImesgQueue, NULL);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Graphics_SetTask(void) {
|
2024-04-25 07:14:49 +03:00
|
|
|
gGfxTask->mesgQueue = &gGfxTaskMesgQueue;
|
2023-11-13 01:49:03 +03:00
|
|
|
gGfxTask->msg = (OSMesg) TASK_MESG_2;
|
2023-11-08 01:32:09 +03:00
|
|
|
gGfxTask->task.t.type = M_GFXTASK;
|
|
|
|
gGfxTask->task.t.flags = 0;
|
2024-02-17 01:04:22 +03:00
|
|
|
gGfxTask->task.t.ucode_boot = rspbootTextStart;
|
|
|
|
gGfxTask->task.t.ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
|
|
|
|
gGfxTask->task.t.ucode = gspF3DEX_fifoTextStart;
|
2023-12-07 03:16:49 +03:00
|
|
|
gGfxTask->task.t.ucode_size = SP_UCODE_SIZE;
|
2024-02-17 01:04:22 +03:00
|
|
|
gGfxTask->task.t.ucode_data = (u64*) &gspF3DEX_fifoDataStart;
|
2023-12-07 03:16:49 +03:00
|
|
|
gGfxTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
|
2023-12-15 23:09:49 +03:00
|
|
|
gGfxTask->task.t.dram_stack = gDramStack;
|
2023-12-07 03:16:49 +03:00
|
|
|
gGfxTask->task.t.dram_stack_size = SP_DRAM_STACK_SIZE8;
|
2023-12-15 23:09:49 +03:00
|
|
|
gGfxTask->task.t.output_buff = (u64*) gTaskOutputBuffer;
|
2024-02-24 04:56:08 +03:00
|
|
|
gGfxTask->task.t.output_buff_size = (u64*) gAudioHeap;
|
2023-11-08 01:32:09 +03:00
|
|
|
gGfxTask->task.t.data_ptr = (u64*) gGfxPool->masterDL;
|
|
|
|
gGfxTask->task.t.data_size = (gMasterDisp - gGfxPool->masterDL) * sizeof(Gfx);
|
2023-12-15 23:09:49 +03:00
|
|
|
gGfxTask->task.t.yield_data_ptr = (u64*) &gOSYieldData;
|
2023-11-08 01:32:09 +03:00
|
|
|
gGfxTask->task.t.yield_data_size = OS_YIELD_DATA_SIZE;
|
|
|
|
osWritebackDCacheAll();
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gTaskMesgQueue, gGfxTask, OS_MESG_NOBLOCK);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Graphics_InitializeTask(u32 frameCount) {
|
|
|
|
gGfxPool = &gGfxPools[frameCount % 2];
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-08 01:32:09 +03:00
|
|
|
gGfxTask = &gGfxPool->task;
|
|
|
|
gViewport = gGfxPool->viewports;
|
|
|
|
gGfxMtx = gGfxPool->mtx;
|
|
|
|
gUnkDisp1 = gGfxPool->unkDL1;
|
|
|
|
gMasterDisp = gGfxPool->masterDL;
|
|
|
|
gUnkDisp2 = gGfxPool->unkDL2;
|
|
|
|
gLight = gGfxPool->lights;
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
gFrameBuffer = &gFrameBuffers[frameCount % 3];
|
2023-12-15 23:09:49 +03:00
|
|
|
gTextureRender = &gTextureRenderBuffer[0];
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
gGfxMatrix = &sGfxMatrixStack[0];
|
|
|
|
gCalcMatrix = &sCalcMatrixStack[0];
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-12-09 21:53:24 +03:00
|
|
|
D_80178710 = &D_80178580[0];
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_SetVIMode(void) {
|
2023-12-20 22:32:50 +03:00
|
|
|
if ((gControllerHold[0].button & D_JPAD) && (gControllerHold[1].button & D_JPAD) &&
|
|
|
|
(gControllerHold[2].button & D_JPAD) && (gControllerHold[3].button & L_TRIG) &&
|
|
|
|
(gControllerHold[3].button & R_TRIG) && (gControllerHold[3].button & Z_TRIG)) {
|
2023-11-24 22:11:20 +03:00
|
|
|
sGammaMode = 1 - sGammaMode;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
switch (osTvType) {
|
2023-11-24 22:11:20 +03:00
|
|
|
case OS_TV_PAL:
|
2023-11-08 01:32:09 +03:00
|
|
|
osViSetMode(&osViModePalLan1);
|
|
|
|
break;
|
2023-11-24 22:11:20 +03:00
|
|
|
case OS_TV_MPAL:
|
2023-11-08 01:32:09 +03:00
|
|
|
osViSetMode(&osViModeMpalLan1);
|
|
|
|
break;
|
|
|
|
default:
|
2023-11-24 22:11:20 +03:00
|
|
|
case OS_TV_NTSC:
|
2023-11-08 01:32:09 +03:00
|
|
|
osViSetMode(&osViModeNtscLan1);
|
|
|
|
break;
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
if (sGammaMode != 0) {
|
2023-11-08 01:32:09 +03:00
|
|
|
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_ON | OS_VI_GAMMA_DITHER_ON);
|
|
|
|
} else {
|
|
|
|
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_OFF | OS_VI_GAMMA_DITHER_OFF);
|
|
|
|
}
|
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-13 01:49:03 +03:00
|
|
|
void SerialInterface_ThreadEntry(void* arg0) {
|
|
|
|
OSMesg sp34;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
Controller_Init();
|
2023-11-08 01:32:09 +03:00
|
|
|
while (1) {
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gSerialThreadMesgQueue, &sp34);
|
2023-11-13 01:49:03 +03:00
|
|
|
|
|
|
|
switch ((s32) sp34) {
|
2023-11-24 22:11:20 +03:00
|
|
|
case SI_READ_CONTROLLER:
|
|
|
|
Controller_ReadData();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-24 22:11:20 +03:00
|
|
|
case SI_READ_SAVE:
|
|
|
|
Save_ReadData();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-24 22:11:20 +03:00
|
|
|
case SI_WRITE_SAVE:
|
|
|
|
Save_WriteData();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-24 22:11:20 +03:00
|
|
|
case SI_RUMBLE:
|
|
|
|
Controller_Rumble();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Timer_ThreadEntry(void* arg0) {
|
2023-11-08 01:32:09 +03:00
|
|
|
void* sp24;
|
|
|
|
|
|
|
|
while (1) {
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gTimerTaskMesgQueue, &sp24);
|
2023-11-24 22:11:20 +03:00
|
|
|
Timer_CompleteTask(sp24);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Graphics_ThreadEntry(void* arg0) {
|
|
|
|
u8 i;
|
2024-04-11 19:55:32 +03:00
|
|
|
u8 visPerFrame;
|
|
|
|
u8 validVIsPerFrame;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2023-12-14 17:41:43 +03:00
|
|
|
Game_Initialize();
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gSerialThreadMesgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_NOBLOCK);
|
2024-01-17 18:36:58 +03:00
|
|
|
Graphics_InitializeTask(gSysFrameCount);
|
2023-11-08 01:32:09 +03:00
|
|
|
{
|
|
|
|
gSPSegment(gUnkDisp1++, 0, 0);
|
|
|
|
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL1);
|
2024-02-17 01:04:22 +03:00
|
|
|
Game_Update();
|
2023-11-08 01:32:09 +03:00
|
|
|
gSPEndDisplayList(gUnkDisp1++);
|
|
|
|
gSPEndDisplayList(gUnkDisp2++);
|
|
|
|
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL2);
|
|
|
|
gDPFullSync(gMasterDisp++);
|
|
|
|
gSPEndDisplayList(gMasterDisp++);
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
Graphics_SetTask();
|
2023-11-08 01:32:09 +03:00
|
|
|
while (1) {
|
2024-01-17 18:36:58 +03:00
|
|
|
gSysFrameCount++;
|
|
|
|
Graphics_InitializeTask(gSysFrameCount);
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gControllerMesgQueue, NULL);
|
|
|
|
osSendMesg(&gSerialThreadMesgQueue, (OSMesg) SI_RUMBLE, OS_MESG_NOBLOCK);
|
2023-11-24 22:11:20 +03:00
|
|
|
Controller_UpdateInput();
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gSerialThreadMesgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_NOBLOCK);
|
2023-12-20 22:32:50 +03:00
|
|
|
if (gControllerPress[3].button & U_JPAD) {
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_SetVIMode();
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
{
|
|
|
|
gSPSegment(gUnkDisp1++, 0, 0);
|
|
|
|
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL1);
|
2024-02-17 01:04:22 +03:00
|
|
|
Game_Update();
|
2023-11-24 22:11:20 +03:00
|
|
|
if (gStartNMI == 1) {
|
2023-11-30 05:44:42 +03:00
|
|
|
Graphics_NMIWipe();
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
gSPEndDisplayList(gUnkDisp1++);
|
|
|
|
gSPEndDisplayList(gUnkDisp2++);
|
|
|
|
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL2);
|
|
|
|
gDPFullSync(gMasterDisp++);
|
|
|
|
gSPEndDisplayList(gMasterDisp++);
|
|
|
|
}
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gGfxTaskMesgQueue, NULL);
|
2023-11-24 22:11:20 +03:00
|
|
|
Graphics_SetTask();
|
|
|
|
if (gFillScreen == 0) {
|
2024-01-17 18:36:58 +03:00
|
|
|
osViSwapBuffer(&gFrameBuffers[(gSysFrameCount - 1) % 3]);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2024-01-17 18:36:58 +03:00
|
|
|
func_80007FE4(&gFrameBuffers[(gSysFrameCount - 1) % 3], SCREEN_WIDTH, 16);
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
visPerFrame = MIN(gVIsPerFrame, 4);
|
2024-04-25 07:14:49 +03:00
|
|
|
validVIsPerFrame = MAX(visPerFrame, gGfxVImesgQueue.validCount + 1);
|
2024-04-11 19:55:32 +03:00
|
|
|
for (i = 0; i < validVIsPerFrame; i += 1) { // Can't be ++
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gGfxVImesgQueue, NULL);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
|
2024-03-01 21:57:44 +03:00
|
|
|
Audio_Update();
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-13 01:49:03 +03:00
|
|
|
void Main_InitMesgQueues(void) {
|
2024-04-25 07:14:49 +03:00
|
|
|
osCreateMesgQueue(&gDmaMesgQueue, sDmaMsgBuff, ARRAY_COUNT(sDmaMsgBuff));
|
|
|
|
osCreateMesgQueue(&gTaskMesgQueue, sTaskMsgBuff, ARRAY_COUNT(sTaskMsgBuff));
|
|
|
|
osCreateMesgQueue(&gAudioVImesgQueue, sAudioVImsgBuff, ARRAY_COUNT(sAudioVImsgBuff));
|
|
|
|
osCreateMesgQueue(&gAudioTaskMesgQueue, sAudioTaskMsgBuff, ARRAY_COUNT(sAudioTaskMsgBuff));
|
|
|
|
osCreateMesgQueue(&gGfxVImesgQueue, sGfxVImsgBuff, ARRAY_COUNT(sGfxVImsgBuff));
|
|
|
|
osCreateMesgQueue(&gGfxTaskMesgQueue, sGfxTaskMsgBuff, ARRAY_COUNT(sGfxTaskMsgBuff));
|
2023-11-24 22:11:20 +03:00
|
|
|
osCreateMesgQueue(&gSerialEventQueue, sSerialEventBuff, ARRAY_COUNT(sSerialEventBuff));
|
2023-11-13 01:49:03 +03:00
|
|
|
osSetEventMesg(OS_EVENT_SI, &gSerialEventQueue, NULL);
|
2024-04-25 07:14:49 +03:00
|
|
|
osCreateMesgQueue(&gMainThreadMesgQueue, sMainThreadMsgBuff, ARRAY_COUNT(sMainThreadMsgBuff));
|
|
|
|
osViSetEvent(&gMainThreadMesgQueue, (OSMesg) EVENT_MESG_VI, 1);
|
|
|
|
osSetEventMesg(OS_EVENT_SP, &gMainThreadMesgQueue, (OSMesg) EVENT_MESG_SP);
|
|
|
|
osSetEventMesg(OS_EVENT_DP, &gMainThreadMesgQueue, (OSMesg) EVENT_MESG_DP);
|
|
|
|
osSetEventMesg(OS_EVENT_PRENMI, &gMainThreadMesgQueue, (OSMesg) EVENT_MESG_PRENMI);
|
|
|
|
osCreateMesgQueue(&gTimerTaskMesgQueue, sTimerTaskMsgBuff, ARRAY_COUNT(sTimerTaskMsgBuff));
|
|
|
|
osCreateMesgQueue(&gTimerWaitMesgQueue, sTimerWaitMsgBuff, ARRAY_COUNT(sTimerWaitMsgBuff));
|
|
|
|
osCreateMesgQueue(&gSerialThreadMesgQueue, sSerialThreadMsgBuff, ARRAY_COUNT(sSerialThreadMsgBuff));
|
|
|
|
osCreateMesgQueue(&gControllerMesgQueue, sControllerMsgBuff, ARRAY_COUNT(sControllerMsgBuff));
|
|
|
|
osCreateMesgQueue(&gSaveMesgQueue, sSaveMsgBuff, ARRAY_COUNT(sSaveMsgBuff));
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_HandleRDP(void) {
|
2024-04-25 07:14:49 +03:00
|
|
|
SPTask** task = sGfxTasks;
|
2023-11-08 01:32:09 +03:00
|
|
|
u8 i;
|
|
|
|
|
2024-04-25 07:14:49 +03:00
|
|
|
if ((*task)->mesgQueue != NULL) {
|
|
|
|
osSendMesg((*task)->mesgQueue, (*task)->msg, OS_MESG_NOBLOCK);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2024-04-25 07:14:49 +03:00
|
|
|
(*task)->state = SPTASK_STATE_FINISHED_DP;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sGfxTasks) - 1; i += 1, task++) {
|
|
|
|
*task = *(task + 1);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2024-04-25 07:14:49 +03:00
|
|
|
*task = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_HandleRSP(void) {
|
2023-11-08 01:32:09 +03:00
|
|
|
SPTask* task = gCurrentTask;
|
|
|
|
|
|
|
|
gCurrentTask = NULL;
|
|
|
|
if (task->state == SPTASK_STATE_INTERRUPTED) {
|
|
|
|
if (osSpTaskYielded(&task->task) == 0) {
|
|
|
|
task->state = SPTASK_STATE_FINISHED;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
task->state = SPTASK_STATE_FINISHED;
|
|
|
|
if (task->task.t.type == M_AUDTASK) {
|
2024-04-25 07:14:49 +03:00
|
|
|
if (task->mesgQueue != NULL) {
|
|
|
|
osSendMesg(task->mesgQueue, task->msg, OS_MESG_NOBLOCK);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
sAudioTasks[0] = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_GetNewTasks(void) {
|
2023-11-08 01:32:09 +03:00
|
|
|
u8 i;
|
2024-04-11 19:55:32 +03:00
|
|
|
SPTask** audioTask;
|
|
|
|
SPTask** gfxTask;
|
|
|
|
SPTask** newAudioTask;
|
|
|
|
SPTask** newGfxTask;
|
|
|
|
OSMesg spTaskMsg;
|
|
|
|
SPTask* newTask;
|
|
|
|
|
|
|
|
newAudioTask = sNewAudioTasks;
|
|
|
|
newGfxTask = sNewGfxTasks;
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sNewAudioTasks); i += 1) {
|
2024-04-11 19:55:32 +03:00
|
|
|
*(newAudioTask++) = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sNewGfxTasks); i += 1) {
|
2024-04-11 19:55:32 +03:00
|
|
|
*(newGfxTask++) = NULL;
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
newAudioTask = sNewAudioTasks;
|
|
|
|
newGfxTask = sNewGfxTasks;
|
2024-04-25 07:14:49 +03:00
|
|
|
while (MQ_GET_MESG(&gTaskMesgQueue, &spTaskMsg)) {
|
2024-04-11 19:55:32 +03:00
|
|
|
newTask = (SPTask*) spTaskMsg;
|
|
|
|
newTask->state = SPTASK_STATE_NOT_STARTED;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
switch (newTask->task.t.type) {
|
2023-11-13 01:49:03 +03:00
|
|
|
case M_AUDTASK:
|
2024-04-11 19:55:32 +03:00
|
|
|
*(newAudioTask++) = newTask;
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-13 01:49:03 +03:00
|
|
|
case M_GFXTASK:
|
2024-04-11 19:55:32 +03:00
|
|
|
*(newGfxTask++) = newTask;
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-04-11 19:55:32 +03:00
|
|
|
newAudioTask = sNewAudioTasks;
|
|
|
|
newGfxTask = sNewGfxTasks;
|
|
|
|
audioTask = sAudioTasks;
|
|
|
|
gfxTask = sGfxTasks;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sAudioTasks); i += 1, audioTask++) {
|
|
|
|
if (*audioTask == NULL) {
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i; i < ARRAY_COUNT(sAudioTasks); i += 1) {
|
2024-04-11 19:55:32 +03:00
|
|
|
*(audioTask++) = *(newAudioTask++);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
|
2024-04-11 19:55:32 +03:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sGfxTasks); i += 1, gfxTask++) {
|
|
|
|
if (*gfxTask == NULL) {
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
for (i; i < ARRAY_COUNT(sGfxTasks); i += 1) {
|
2024-04-11 19:55:32 +03:00
|
|
|
*(gfxTask++) = *(newGfxTask++);
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-24 22:11:20 +03:00
|
|
|
void Main_StartNextTask(void) {
|
|
|
|
if (sAudioTasks[0] != NULL) {
|
2023-11-08 01:32:09 +03:00
|
|
|
if (gCurrentTask != NULL) {
|
|
|
|
if (gCurrentTask->task.t.type == M_GFXTASK) {
|
|
|
|
gCurrentTask->state = SPTASK_STATE_INTERRUPTED;
|
|
|
|
osSpTaskYield();
|
|
|
|
}
|
|
|
|
} else {
|
2023-11-24 22:11:20 +03:00
|
|
|
gCurrentTask = sAudioTasks[0];
|
2023-11-08 01:32:09 +03:00
|
|
|
osSpTaskLoad(&gCurrentTask->task);
|
|
|
|
osSpTaskStartGo(&gCurrentTask->task);
|
|
|
|
gCurrentTask->state = SPTASK_STATE_RUNNING;
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
} else if ((gCurrentTask == NULL) && (sGfxTasks[0] != NULL) && (sGfxTasks[0]->state != SPTASK_STATE_FINISHED)) {
|
|
|
|
gCurrentTask = sGfxTasks[0];
|
2023-11-08 01:32:09 +03:00
|
|
|
osDpSetStatus(DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_CMD_CTR | DPC_CLR_CLOCK_CTR);
|
|
|
|
osSpTaskLoad(&gCurrentTask->task);
|
|
|
|
osSpTaskStartGo(&gCurrentTask->task);
|
|
|
|
gCurrentTask->state = SPTASK_STATE_RUNNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Main_ThreadEntry(void* arg0) {
|
2024-04-25 07:14:49 +03:00
|
|
|
OSMesg osMesg;
|
2023-11-13 01:49:03 +03:00
|
|
|
u8 mesg;
|
2023-11-08 01:32:09 +03:00
|
|
|
|
|
|
|
osCreateThread(&gAudioThread, THREAD_ID_AUDIO, Audio_ThreadEntry, arg0,
|
|
|
|
gAudioThreadStack + sizeof(gAudioThreadStack), 80);
|
|
|
|
osStartThread(&gAudioThread);
|
|
|
|
osCreateThread(&gGraphicsThread, THREAD_ID_GRAPHICS, Graphics_ThreadEntry, arg0,
|
|
|
|
gGraphicsThreadStack + sizeof(gGraphicsThreadStack), 40);
|
|
|
|
osStartThread(&gGraphicsThread);
|
2023-12-24 22:28:35 +03:00
|
|
|
osCreateThread(&gTimerThread, THREAD_ID_TIMER, Timer_ThreadEntry, arg0,
|
|
|
|
gTimerThreadStack + sizeof(gTimerThreadStack), 60);
|
2023-11-24 22:11:20 +03:00
|
|
|
osStartThread(&gTimerThread);
|
2023-11-13 01:49:03 +03:00
|
|
|
osCreateThread(&gSerialThread, THREAD_ID_SERIAL, SerialInterface_ThreadEntry, arg0,
|
|
|
|
gSerialThreadStack + sizeof(gSerialThreadStack), 20);
|
|
|
|
osStartThread(&gSerialThread);
|
2023-11-08 01:32:09 +03:00
|
|
|
|
2023-11-13 01:49:03 +03:00
|
|
|
Main_InitMesgQueues();
|
2023-11-08 01:32:09 +03:00
|
|
|
|
|
|
|
while (true) {
|
2024-04-25 07:14:49 +03:00
|
|
|
MQ_WAIT_FOR_MESG(&gMainThreadMesgQueue, &osMesg);
|
|
|
|
mesg = (u32) osMesg;
|
2023-11-13 01:49:03 +03:00
|
|
|
|
|
|
|
switch (mesg) {
|
|
|
|
case EVENT_MESG_VI:
|
2024-04-25 07:14:49 +03:00
|
|
|
osSendMesg(&gAudioVImesgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_NOBLOCK);
|
|
|
|
osSendMesg(&gGfxVImesgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_NOBLOCK);
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_GetNewTasks();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-13 01:49:03 +03:00
|
|
|
case EVENT_MESG_SP:
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_HandleRSP();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-13 01:49:03 +03:00
|
|
|
case EVENT_MESG_DP:
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_HandleRDP();
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
2023-11-13 01:49:03 +03:00
|
|
|
case EVENT_MESG_PRENMI:
|
2023-11-24 22:11:20 +03:00
|
|
|
gStartNMI = 1;
|
2023-11-08 01:32:09 +03:00
|
|
|
break;
|
|
|
|
}
|
2023-11-24 22:11:20 +03:00
|
|
|
if (gStopTasks == 0) {
|
|
|
|
Main_StartNextTask();
|
2023-11-08 01:32:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-11-08 01:32:09 +03:00
|
|
|
void Idle_ThreadEntry(void* arg0) {
|
|
|
|
osCreateViManager(OS_PRIORITY_VIMGR);
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_SetVIMode();
|
|
|
|
Lib_FillScreen(1);
|
2023-12-07 03:16:49 +03:00
|
|
|
osCreatePiManager(OS_PRIORITY_PIMGR, &gPiMgrCmdQueue, sPiMgrCmdBuff, ARRAY_COUNT(sPiMgrCmdBuff));
|
2023-11-08 01:32:09 +03:00
|
|
|
osCreateThread(&gMainThread, THREAD_ID_MAIN, &Main_ThreadEntry, arg0, sMainThreadStack + sizeof(sMainThreadStack),
|
|
|
|
100);
|
|
|
|
osStartThread(&gMainThread);
|
2023-11-13 01:49:03 +03:00
|
|
|
Fault_Init();
|
2023-11-08 01:32:09 +03:00
|
|
|
osSetThreadPri(NULL, OS_PRIORITY_IDLE);
|
2023-10-07 14:43:15 +03:00
|
|
|
loop_1:
|
|
|
|
goto loop_1;
|
|
|
|
}
|
2023-10-06 15:57:30 +03:00
|
|
|
|
2023-10-07 09:29:38 +03:00
|
|
|
void bootproc(void) {
|
2023-11-08 01:32:09 +03:00
|
|
|
RdRam_CheckIPL3();
|
2023-11-03 02:36:13 +03:00
|
|
|
osInitialize();
|
2023-11-24 22:11:20 +03:00
|
|
|
Main_Initialize();
|
2023-11-08 01:32:09 +03:00
|
|
|
osCreateThread(&sIdleThread, THREAD_ID_IDLE, &Idle_ThreadEntry, NULL, sIdleThreadStack + sizeof(sIdleThreadStack),
|
|
|
|
255);
|
|
|
|
osStartThread(&sIdleThread);
|
2023-10-07 09:29:38 +03:00
|
|
|
}
|