diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 736138cb..d2cbf982 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -5143,7 +5143,7 @@ lbl_8013219C = .data:0x8013219C; // type:object size:0xC data:string lbl_801321A8 = .data:0x801321A8; // type:object size:0xC data:string SaveFileNameTbl = .data:0x801321B4; // type:object size:0xC jumptable_801321C0 = .data:0x801321C0; // type:object size:0x34 scope:local -SR_PreRstChk = .data:0x801321F8; // type:object size:0x10 +SR_PreRstChk = .data:0x801321F8; // type:object size:0x10 scope:local coveropen_en = .data:0x80132208; // type:object size:0x1384 noreloc fatalerror_en = .data:0x8013358C; // type:object size:0x1384 noreloc loading_en = .data:0x80134910; // type:object size:0x1384 noreloc diff --git a/configure.py b/configure.py index 84efbee8..4b9440b4 100644 --- a/configure.py +++ b/configure.py @@ -358,7 +358,7 @@ config.libs = [ Object(Matching, "game/objsub.c"), Object(Matching, "game/flag.c"), Object(Matching, "game/saveload.c"), - Object(NonMatching, "game/sreset.c"), + Object(Matching, "game/sreset.c"), Object(Matching, "game/board/main.c"), Object(NonMatching, "game/board/player.c"), Object(Matching, "game/board/model.c"), diff --git a/include/game/pad.h b/include/game/pad.h index a771d2c2..2223f0b4 100644 --- a/include/game/pad.h +++ b/include/game/pad.h @@ -22,7 +22,7 @@ extern u8 HuPadDStkRep[4]; extern s8 HuPadErr[4]; extern u16 _PadBtn[4]; extern u16 _PadBtnDown[4]; -extern u32 VCounter; +extern s32 VCounter; void HuPadInit(void); void HuPadRead(void); diff --git a/include/game/thpmain.h b/include/game/thpmain.h index b0d5b0d1..13fb8e2c 100644 --- a/include/game/thpmain.h +++ b/include/game/thpmain.h @@ -2,6 +2,8 @@ #define _GAME_THPMAIN_H #include "dolphin/types.h" +#include "game/process.h" + s16 HuTHPSprCreateVol(char *path, s16 loop, s16 prio, float volume); s16 HuTHPSprCreate(char *path, s16 loop, s16 prio); @@ -15,4 +17,7 @@ s32 HuTHPFrameGet(void); s32 HuTHPTotalFrameGet(void); void HuTHPSetVolume(s32 left, s32 right); +extern Process *THPProc; + + #endif \ No newline at end of file diff --git a/src/game/pad.c b/src/game/pad.c index 139e879f..cded2f4f 100644 --- a/src/game/pad.c +++ b/src/game/pad.c @@ -43,7 +43,7 @@ static u8 _PadDStkRepCnt[4]; static u8 _PadDStkRepOld[4]; static s8 _PadErr[4]; static u32 RumbleBit; -u32 VCounter; +s32 VCounter; static u32 chanTbl[4] = { PAD_CHAN0_BIT, PAD_CHAN1_BIT, PAD_CHAN2_BIT, PAD_CHAN3_BIT }; diff --git a/src/game/sreset.c b/src/game/sreset.c new file mode 100644 index 00000000..04ca1a70 --- /dev/null +++ b/src/game/sreset.c @@ -0,0 +1,422 @@ +#include "dolphin.h" +#include "game/flag.h" +#include "game/dvd.h" +#include "game/pad.h" +#include "game/audio.h" +#include "game/thpmain.h" + +#define SR_DVD_LOADING 0 +#define SR_DVD_COVER_OPEN 1 +#define SR_DVD_NO_DISK 2 +#define SR_DVD_WRONG_DISK 3 +#define SR_DVD_RETRY_ERROR 4 +#define SR_DVD_FATAL_ERROR 5 + +#define PAD_BTN_SRESET (PAD_BUTTON_START|PAD_BUTTON_X|PAD_BUTTON_B) +#define PAD_BTN_SRESET_SHORT (PAD_BUTTON_X|PAD_BUTTON_B) + +extern s32 HuDvdErrWait; + +static s32 SR_PreRstChk[4] = {}; + +#include "coveropen_en.inc" +#include "fatalerror_en.inc" +#include "loading_en.inc" +#include "nodisc_en.inc" +#include "retryerror_en.inc" +#include "wrongdisc_en.inc" + +static s16 SR_PushTime[4] = {}; +static s8 SR_ResetPad = -1; + +static s16 XfbW; +static s16 XfbH; +static s32 XfbProg; +static void *Xfb[2] = {}; +static BOOL trychkBusyWait; +s32 SR_ExecReset; +static s32 SR_RestartChk; +static BOOL H_ResetReady; + +void HuRestartSystem(void); + +s32 HuSoftResetCheck(void); +s32 HuSoftResetCountCheck(void); +static void HuSoftResetPostProc(void); + +s32 HuSoftResetButtonCheck(void) +{ + if(SR_ExecReset) { + HuRestartSystem(); + } + return (SR_ExecReset) ? 1 : 0; +} + +static OSMessageQueue ToeMessageQueue; + +void HuDvdErrDispIntFunc(u32 retraceCount) +{ + OSWakeupThread(&ToeMessageQueue.queueSend); +} + +static void HuPreRstChk(void) +{ + static PADStatus padStat[4]; + int i; + PADRead(padStat); + for(i=0; i<4; i++) { + PADStatus *status = &padStat[i]; + if(status->err != 0) { + continue; + } + if((status->button & PAD_BTN_SRESET) == PAD_BTN_SRESET) { + SR_PreRstChk[i] = 1; + } else { + SR_PreRstChk[i] = 0; + } + } +} + +static OSMessage ToeMessageArray[16]; +static OSThread ToeThread; +static u8 ToeThreadStack[4096]; + +static void *ToeThreadFunc(void *param); +static void ToeDispCheck(void); + +void HuDvdErrDispInit(GXRenderModeObj *rmode, void *xfb1, void *xfb2) +{ + BOOL intrOld; + _ClearFlag(0x30000); + SR_ResetPad = -1; + SR_ExecReset = H_ResetReady = 0; + SR_RestartChk = 0; + SR_PushTime[0] = SR_PushTime[1] = SR_PushTime[2] = SR_PushTime[3] = 0; + VIWaitForRetrace(); + VIWaitForRetrace(); + VIWaitForRetrace(); + HuPreRstChk(); + HuDvdErrWait = 0; + Xfb[0] = xfb1; + Xfb[1] = xfb2; + if(rmode) { + XfbW = (u16)(((u16)rmode->fbWidth+15) & ~0xF); + XfbH = rmode->xfbHeight; + } else { + XfbW = 640; + XfbH = 480; + } + if((u16)rmode->xFBmode == VI_XFBMODE_SF) { + XfbProg = 0; + } else { + XfbProg = 1; + } + trychkBusyWait = FALSE; + OSInitMessageQueue(&ToeMessageQueue, ToeMessageArray, 16); + OSCreateThread(&ToeThread, ToeThreadFunc, NULL, &ToeThreadStack[4096], 4096, 8, OS_THREAD_ATTR_DETACH); + OSResumeThread(&ToeThread); + intrOld = OSDisableInterrupts(); + VISetPreRetraceCallback(HuDvdErrDispIntFunc); + OSRestoreInterrupts(intrOld); +} + +static void *ToeThreadFunc(void *param) +{ + while(1) { + BOOL hide_disp; + OSSleepThread(&ToeMessageQueue.queueSend); + if(!_CheckFlag(0x30000)) { + BOOL reset; + if(!HuSoftResetCheck()) { + if(SR_ExecReset) { + reset = TRUE; + } else { + if(H_ResetReady == TRUE && OSGetResetButtonState() != TRUE) { + reset = TRUE; + } else { + if(H_ResetReady != TRUE && OSGetResetButtonState() == TRUE) { + H_ResetReady = TRUE; + } + reset = FALSE; + } + } + if(reset) { + proc_reset: + HuSoftResetPostProc(); + } + } else { + goto proc_reset; + } + } + if(SR_ExecReset) { + HuRestartSystem(); + } + if(SR_ExecReset) { + hide_disp = TRUE; + } else { + hide_disp = FALSE; + } + if(!hide_disp) { + ToeDispCheck(); + } + } +} + +static void _HuDvdErrDispXFB(s32 error); + +static void ToeDispCheck(void) +{ + s32 status; + if(SR_ResetPad != -1 || SR_ExecReset != FALSE || SR_RestartChk != 0) { + return; + } + status = DVDGetDriveStatus(); + switch(status) { + case DVD_STATE_FATAL_ERROR: + status = SR_DVD_FATAL_ERROR; + trychkBusyWait = TRUE; + break; + + case DVD_STATE_END: + HuDvdErrWait = 0; + trychkBusyWait = FALSE; + return; + + case DVD_STATE_COVER_OPEN: + status = SR_DVD_COVER_OPEN; + trychkBusyWait = TRUE; + break; + + case DVD_STATE_BUSY: + case DVD_STATE_COVER_CLOSED: + if(!trychkBusyWait) { + return; + } + status = SR_DVD_LOADING; + break; + + case DVD_STATE_NO_DISK: + status = SR_DVD_NO_DISK; + trychkBusyWait = TRUE; + break; + + case DVD_STATE_WRONG_DISK: + status = SR_DVD_WRONG_DISK; + trychkBusyWait = TRUE; + break; + + case DVD_STATE_RETRY: + status = SR_DVD_RETRY_ERROR; + trychkBusyWait = TRUE; + break; + + default: + return; + } + HuDvdErrWait = 1; + HuPadRumbleAllStop(); + VISetBlack(FALSE); + VIFlush(); + if(msmSysCheckInit()) { + HuAudSStreamAllStop(); + } + _HuDvdErrDispXFB(status); +} + +static void _HuDvdErrDispXFB(s32 error) +{ + static void *bmpMes[][6] = { + loading_en, coveropen_en, nodisc_en, wrongdisc_en, retryerror_en, fatalerror_en + }; + volatile s32 status; + u8 color[2]; + s8 language; + s16 *bmpData; + u8 *xfb1_ptr; + u8 *xfb2_ptr; + u32 i; + u32 data; + u32 row; + u32 *xfb1; + u32 *xfb2; + u32 j; + u8 y1; + u8 y2; + s32 reset; + u32 *data_ptr; + u32 row_offset; + u32 row_pitch; + language = 0; + xfb1 = Xfb[0]; + xfb2 = Xfb[1]; + for(i=0; i<0x25800; i++, xfb1++, xfb2++) { + *xfb1 = *xfb2 = 0x800080; + } + DCStoreRangeNoSync(Xfb[0], 0x96000); + DCStoreRangeNoSync(Xfb[1], 0x96000); + bmpData = bmpMes[language][error]; + data_ptr = (u32 *)(bmpData+2); + row_offset = ((XfbW/2)-(bmpData[0]/2))*2; + row_pitch = XfbW*2; + color[1] = color[0] = 128; + for(row=0; row>= 2, xfb1_ptr += 4, xfb2_ptr += 4) { + if(data & 0x3){ + if(data & 0x1) { + y1 = 0xEB; + } else { + y1 = 0x10; + } + if(data & 0x2) { + y2 = 0xEB; + } else { + y2 = 0x10; + } + xfb1_ptr[0] = y1; + xfb1_ptr[1] = color[1]; + xfb1_ptr[2] = y2; + xfb1_ptr[3] = color[0]; + xfb2_ptr[0] = y1; + xfb2_ptr[1] = color[1]; + xfb2_ptr[2] = y2; + xfb2_ptr[3] = color[0]; + } + } + } + DCStoreRangeNoSync(sp14[1], bmpData[0]*2); + DCStoreRangeNoSync(sp14[0], bmpData[0]*2); + } + status = DVDGetDriveStatus(); + while(status) { + if(status != DVDGetDriveStatus()) { + break; + } + if(SR_ExecReset) { + reset = TRUE; + } else { + if(H_ResetReady == TRUE && OSGetResetButtonState() != TRUE) { + reset = TRUE; + } else { + if(H_ResetReady != TRUE && OSGetResetButtonState() == TRUE) { + H_ResetReady = TRUE; + } + reset = FALSE; + } + } + if(reset) { + if(msmSysCheckInit()) { + msmStreamSetMasterVolume(0); + msmSeSetMasterVolume(0); + msmMusSetMasterVolume(0); + } + HuRestartSystem(); + } + + OSYieldThread(); + } +} + +void HuRestartSystem(void) +{ + u32 retrace[2]; + BOOL prevInt; + if(SR_RestartChk) { + return; + } + SR_RestartChk = TRUE; + PADRecalibrate(PAD_CHAN0_BIT|PAD_CHAN1_BIT|PAD_CHAN2_BIT|PAD_CHAN3_BIT); + msmSysCheckInit(); + VISetBlack(TRUE); + VIFlush(); + prevInt = OSDisableInterrupts(); + if(!prevInt) { + OSReport("PrevInt=DISABLE!!\n"); + } + OSEnableInterrupts(); + retrace[1] = VIGetRetraceCount(); + retrace[0] = 0; + while(retrace[1] == VIGetRetraceCount()) { + if(retrace[0]++ >= 1349800) { + break; + } + } + OSReport("Timeout Count=%d\n", retrace[0]); + __GXAbortWaitPECopyDone(); + OSResetSystem(0, 0, 0); +} + +s32 HuSoftResetCheck(void) +{ + int i; + if(VCounter == 0) { + return 0; + } + if(SR_ExecReset) { + return 1; + } + if(SR_ResetPad != -1) { + if(!(_PadBtn[SR_ResetPad] & PAD_BTN_SRESET)) { + return 1; + } + } else { + for(i=0; i<4; i++) { + if(SR_PreRstChk[i] && (_PadBtn[i] & PAD_BTN_SRESET) != PAD_BTN_SRESET) { + SR_PreRstChk[i] = 0; + } + } + } + + if(HuSoftResetCountCheck()) { + return 1; + } else { + return 0; + } +} + +s32 HuSoftResetCountCheck(void) +{ + int i; + for(i=0; i<4; i++) { + if((_PadBtn[i] & PAD_BTN_SRESET_SHORT) != PAD_BTN_SRESET_SHORT) { + SR_PushTime[i] = 0; + } else { + if(!SR_PreRstChk[i]) { + if(_PadBtn[i] & PAD_BUTTON_START) { + if(SR_PushTime[i]++ >= 30) { + SR_ResetPad = i; + return 1; + } + } else { + SR_PushTime[i] = 0; + } + } + } + } + return 0; +} + +static void HuSoftResetPostProc(void) +{ + if(!SR_ExecReset) { + VISetBlack(TRUE); + VIFlush(); + if(THPProc) { + HuTHPStop(); + HuTHPClose(); + } + if(msmSysCheckInit()) { + msmStreamSetMasterVolume(0); + msmSeSetMasterVolume(0); + msmMusSetMasterVolume(0); + } + HuPadRumbleAllStop(); + SR_ExecReset = TRUE; + } +} \ No newline at end of file