233 lines
6.1 KiB
C
233 lines
6.1 KiB
C
// Quicksaving is disabled for now
|
|
|
|
/* To reenable it, a few changes to the recompiled functions are also needed:
|
|
|
|
in Main:
|
|
L_80174E84:
|
|
// or $a0, $s3, $zero
|
|
ctx->r4 = ctx->r19 | 0;
|
|
// addiu $a1, $sp, 0x38
|
|
ctx->r5 = ADD32(ctx->r29, 0X38);
|
|
// jal 0x80087ED0
|
|
// addiu $a2, $zero, 0x1
|
|
ctx->r6 = ADD32(0, 0X1);
|
|
osRecvMesg_recomp(rdram, ctx);
|
|
+handle_quicksave_actions(rdram, ctx);
|
|
|
|
in Graph_ThreadEntry:
|
|
L_801749C8:
|
|
+handle_quicksave_actions_main(rdram, ctx);
|
|
+ctx->r4 = ctx->r17 | 0;
|
|
// jal 0x80174868
|
|
// or $a1, $s0, $zero
|
|
ctx->r5 = ctx->r16 | 0;
|
|
Graph_Update(rdram, ctx);
|
|
|
|
in PadMgr_ThreadEntry:
|
|
L_801760A0:
|
|
// or $a1, $s2, $zero
|
|
ctx->r5 = ctx->r18 | 0;
|
|
// jal 0x80087ED0
|
|
// or $a2, $s3, $zero
|
|
ctx->r6 = ctx->r19 | 0;
|
|
osRecvMesg_recomp(rdram, ctx);
|
|
+handle_quicksave_actions(rdram, ctx);
|
|
|
|
in AudioMgr_ThreadEntry:
|
|
L_80172F58:
|
|
+handle_quicksave_actions(rdram, ctx);
|
|
+ctx->r4 = ctx->r22 | 0;
|
|
// or $a1, $s2, $zero
|
|
ctx->r5 = ctx->r18 | 0;
|
|
// jal 0x80087ED0
|
|
// or $a2, $s3, $zero
|
|
ctx->r6 = ctx->r19 | 0;
|
|
osRecvMesg_recomp(rdram, ctx);
|
|
|
|
*/
|
|
|
|
#if 0
|
|
|
|
#include "patches.h"
|
|
#include "input.h"
|
|
#include "audiomgr.h"
|
|
|
|
// ultramodern's message queues can be statically initialized, so we don't actually need to call osCreateMesgQueue for these.
|
|
OSMesg quicksave_enter_mq_buffer[20];
|
|
OSMesgQueue quicksave_enter_mq = {
|
|
.msgCount = ARRAY_COUNT(quicksave_enter_mq_buffer),
|
|
.msg = quicksave_enter_mq_buffer,
|
|
.validCount = 0,
|
|
.first = 0
|
|
};
|
|
|
|
OSMesg quicksave_exit_mq_buffer[20];
|
|
OSMesgQueue quicksave_exit_mq = {
|
|
.msgCount = ARRAY_COUNT(quicksave_exit_mq_buffer),
|
|
.msg = quicksave_exit_mq_buffer,
|
|
.validCount = 0,
|
|
.first = 0
|
|
};
|
|
|
|
void handle_quicksave_actions() {
|
|
recomp_handle_quicksave_actions(&quicksave_enter_mq, &quicksave_exit_mq);
|
|
}
|
|
|
|
extern OSMesgQueue sIrqMgrMsgQueue; // For Main thread
|
|
s16 main_irq_message = 0; // dummy value for sending a pointer to the main thread
|
|
|
|
#define RECOMP_IRQ_QUICKSAVE 0x2A2
|
|
|
|
void IrqMgr_ThreadEntry(IrqMgr* irqmgr) {
|
|
u32 interrupt;
|
|
u32 stop;
|
|
|
|
interrupt = 0;
|
|
stop = 0;
|
|
while (stop == 0) {
|
|
if (stop) {
|
|
;
|
|
}
|
|
|
|
osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, OS_MESG_BLOCK);
|
|
switch (interrupt) {
|
|
case 0x29A:
|
|
IrqMgr_HandleRetrace(irqmgr);
|
|
break;
|
|
case 0x29D:
|
|
IrqMgr_HandlePreNMI(irqmgr);
|
|
break;
|
|
case 0x29F:
|
|
IrqMgr_HandlePRENMI450(irqmgr);
|
|
break;
|
|
case 0x2A0:
|
|
IrqMgr_HandlePRENMI480(irqmgr);
|
|
break;
|
|
case 0x2A1:
|
|
IrqMgr_HandlePRENMI500(irqmgr);
|
|
break;
|
|
case RECOMP_IRQ_QUICKSAVE:
|
|
handle_quicksave_actions();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern IrqMgr gIrqMgr;
|
|
|
|
#define RSP_DONE_MSG 667
|
|
#define RDP_DONE_MSG 668
|
|
#define ENTRY_MSG 670
|
|
#define RDP_AUDIO_CANCEL_MSG 671
|
|
#define RSP_GFX_CANCEL_MSG 672
|
|
#define RECOMP_QUICKSAVE_ACTION 673 // @recomp
|
|
|
|
|
|
void Sched_ThreadEntry(void* arg) {
|
|
s32 msg = 0;
|
|
SchedContext* sched = (SchedContext*)arg;
|
|
|
|
while (true) {
|
|
osRecvMesg(&sched->interruptQ, (OSMesg*)&msg, OS_MESG_BLOCK);
|
|
|
|
// Check if it's a message from another thread or the OS
|
|
switch (msg) {
|
|
case RDP_AUDIO_CANCEL_MSG:
|
|
Sched_HandleAudioCancel(sched);
|
|
continue;
|
|
|
|
case RSP_GFX_CANCEL_MSG:
|
|
Sched_HandleGfxCancel(sched);
|
|
continue;
|
|
|
|
case ENTRY_MSG:
|
|
Sched_HandleEntry(sched);
|
|
continue;
|
|
|
|
case RSP_DONE_MSG:
|
|
Sched_HandleRSPDone(sched);
|
|
continue;
|
|
|
|
case RDP_DONE_MSG:
|
|
Sched_HandleRDPDone(sched);
|
|
continue;
|
|
|
|
case RECOMP_QUICKSAVE_ACTION:
|
|
handle_quicksave_actions();
|
|
continue;
|
|
}
|
|
|
|
// Check if it's a message from the IrqMgr
|
|
switch (((OSScMsg*)msg)->type) {
|
|
case OS_SC_RETRACE_MSG:
|
|
Sched_HandleRetrace(sched);
|
|
continue;
|
|
|
|
case OS_SC_PRE_NMI_MSG:
|
|
Sched_HandleReset(sched);
|
|
continue;
|
|
|
|
case OS_SC_NMI_MSG:
|
|
Sched_HandleStop(sched);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern PadMgr* sPadMgrInstance;
|
|
s16 padmgr_dummy_message = 0;
|
|
|
|
extern AudioMgr sAudioMgr;
|
|
s16 audiomgr_dummy_message = 0;
|
|
|
|
extern OSMesgQueue sDmaMgrMsgQueue;
|
|
#define RECOMP_DMAMGR_QUICKSAVE_MESSAGE 1
|
|
|
|
void DmaMgr_ThreadEntry(void* a0) {
|
|
OSMesg msg;
|
|
DmaRequest* req;
|
|
|
|
while (1) {
|
|
osRecvMesg(&sDmaMgrMsgQueue, &msg, OS_MESG_BLOCK);
|
|
|
|
if (msg == NULL) {
|
|
break;
|
|
}
|
|
|
|
if (msg == (OSMesg)RECOMP_DMAMGR_QUICKSAVE_MESSAGE) {
|
|
handle_quicksave_actions();
|
|
continue;
|
|
}
|
|
|
|
req = (DmaRequest*)msg;
|
|
|
|
DmaMgr_ProcessMsg(req);
|
|
if (req->notifyQueue) {
|
|
osSendMesg(req->notifyQueue, req->notifyMsg, OS_MESG_NOBLOCK);
|
|
}
|
|
}
|
|
}
|
|
|
|
extern Scheduler gScheduler;
|
|
|
|
void handle_quicksave_actions_main() {
|
|
recomp_handle_quicksave_actions_main(&quicksave_enter_mq, &quicksave_exit_mq);
|
|
}
|
|
|
|
void wake_threads_for_quicksave_action() {
|
|
// Wake up the Main thread
|
|
osSendMesg(&sIrqMgrMsgQueue, &main_irq_message, OS_MESG_BLOCK);
|
|
// Wake up the IrqMgr thread
|
|
osSendMesg(&gIrqMgr.irqQueue, (OSMesg)RECOMP_IRQ_QUICKSAVE, OS_MESG_BLOCK);
|
|
// Wake up the PadMgr thread
|
|
osSendMesg(&sPadMgrInstance->interruptQueue, &padmgr_dummy_message, OS_MESG_BLOCK);
|
|
// Wake up the AudioMgr thread
|
|
osSendMesg(&sAudioMgr.interruptQueue, &audiomgr_dummy_message, OS_MESG_BLOCK);
|
|
// Wake up the DmaMgr thread
|
|
osSendMesg(&sDmaMgrMsgQueue, (OSMesg)RECOMP_DMAMGR_QUICKSAVE_MESSAGE, OS_MESG_BLOCK);
|
|
// Wake up the Sched thread
|
|
osSendMesg(&gScheduler.interruptQ, (OSMesg)RECOMP_QUICKSAVE_ACTION, OS_MESG_BLOCK);
|
|
}
|
|
|
|
#endif
|