From ee2fef63513b0fd645b4f2ccdee00b70a1a3f0ec Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 14 Jul 2024 10:36:05 -0700 Subject: [PATCH] m_Do_MemCardRWmng work --- include/dolphin/card.h | 1 + include/m_Do/m_Do_MemCard.h | 9 ++-- include/m_Do/m_Do_MemCardRWmng.h | 2 +- src/m_Do/m_Do_MemCard.cpp | 2 +- src/m_Do/m_Do_MemCardRWmng.cpp | 89 +++++++++++++++++++++++++++----- 5 files changed, 85 insertions(+), 18 deletions(-) diff --git a/include/dolphin/card.h b/include/dolphin/card.h index 14cc3a2cc..6fbede8db 100644 --- a/include/dolphin/card.h +++ b/include/dolphin/card.h @@ -81,6 +81,7 @@ s32 CARDCheck(s32); s32 CARDFreeBlocks(s32, s32*, s32*); s32 CARDRead(CARDFileInfo*, void*, s32, s32); s32 CARDWrite(CARDFileInfo*, const void*, s32, s32); +s32 CARDGetSerialNo(s32, u64*); #ifdef __cplusplus } diff --git a/include/m_Do/m_Do_MemCard.h b/include/m_Do/m_Do_MemCard.h index ec3fd7afb..6053cb73a 100644 --- a/include/m_Do/m_Do_MemCard.h +++ b/include/m_Do/m_Do_MemCard.h @@ -45,10 +45,10 @@ class mDoMemCd_Ctrl_c { s32 checkspace(); void setCardState(s32); - bool isCardCommNone() { return mCardCommand == CARD_NO_COMMAND; } + bool isCardCommNone() { return mCardCommand != NULL; } /* 0x0000 */ u8 mData[0x1650]; - /* 0x1650 */ s32 mCardCommand; + /* 0x1650 */ u8* mCardCommand; /* 0x1654 */ u8* mCardBuf; /* 0x1658 */ u8 mCardSlot; /* 0x1659 */ u8 field_0x1659; @@ -58,7 +58,10 @@ class mDoMemCd_Ctrl_c { /* 0x1660 */ s32 field_0x1660; /* 0x1664 */ OSMutex mMutex; /* 0x167C */ OSCond mCond; - /* 0x1684 */ u32 field_0x1684[5]; + /* 0x1684 */ u32 field_0x1684; + /* 0x1688 */ u64 mCardSerialNo; + /* 0x1690 */ u32 field_0x1690; + /* 0x1694 */ u32 field_0x1694; }; // Size: 0x1698 static int mDoMemCd_main(void*); diff --git a/include/m_Do/m_Do_MemCardRWmng.h b/include/m_Do/m_Do_MemCardRWmng.h index 098c3a4d2..63b833ce7 100644 --- a/include/m_Do/m_Do_MemCardRWmng.h +++ b/include/m_Do/m_Do_MemCardRWmng.h @@ -18,7 +18,7 @@ u32 mDoMemCdRWm_CalcCheckSum(void*, u32); u16 mDoMemCdRWm_CalcCheckSumPictData(void*, u32); BOOL mDoMemCdRWm_TestCheckSumPictData(void*); void mDoMemCdRWm_SetCheckSumPictData(u8*); -unsigned long long mDoMemCdRWm_CalcCheckSumGameData(void*, u32); +u64 mDoMemCdRWm_CalcCheckSumGameData(void*, u32); BOOL mDoMemCdRWm_TestCheckSumGameData(void*); void mDoMemCdRWm_SetCheckSumGameData(u8*, u8); diff --git a/src/m_Do/m_Do_MemCard.cpp b/src/m_Do/m_Do_MemCard.cpp index d5845dfe3..b85ad3004 100644 --- a/src/m_Do/m_Do_MemCard.cpp +++ b/src/m_Do/m_Do_MemCard.cpp @@ -24,7 +24,7 @@ mDoMemCd_Ctrl_c::mDoMemCd_Ctrl_c() { /* 80018D70-80018E18 .text ThdInit__15mDoMemCd_Ctrl_cFv */ void mDoMemCd_Ctrl_c::ThdInit() { CARDInit(); - mCardCommand = 0; + mCardCommand = NULL; mCardBuf = NULL; field_0x1659 = 0; field_0x165A = 2; diff --git a/src/m_Do/m_Do_MemCardRWmng.cpp b/src/m_Do/m_Do_MemCardRWmng.cpp index e85ec9271..da108d3d2 100644 --- a/src/m_Do/m_Do_MemCardRWmng.cpp +++ b/src/m_Do/m_Do_MemCardRWmng.cpp @@ -24,14 +24,6 @@ struct mDoMemCdRWm_HeaderData /* 0x1c20 */ char info[32]; }; -struct card_savedata -{ - u32 saveCount; - u32 field_0x04; - u8 data[0x1ff4]; - u32 csum; -}; - struct card_pictdata { u8 data[0x1ffe]; @@ -41,10 +33,20 @@ struct card_pictdata struct card_gamedata { u8 data[0x768]; - unsigned long long csum; + u64 csum; +}; + +struct card_savedata +{ + u32 saveCount; + u32 field_0x04; + card_gamedata gamedata[3]; + u32 field_0x1658[0x269]; + u32 csum; }; static u8 sTmpBuf[0x2000]; +static u8 sTmpBuf2[0x2000]; static u32 sSaveCount; /* 80019940-80019CE8 .text mDoMemCdRWm_Store__FP12CARDFileInfoPvUl */ @@ -67,7 +69,7 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { memset(sTmpBuf, 0, 0x2000); card_savedata* save = (card_savedata*)sTmpBuf; save->field_0x04 = 0; - memcpy(save->data, data, size); + memcpy(save->gamedata, data, size); save->saveCount = ++sSaveCount; s32 csum = mDoMemCdRWm_CalcCheckSum(data, 0x1FFC); save->csum = csum; @@ -118,8 +120,69 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { } /* 80019CE8-80019F4C .text mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl */ -s32 mDoMemCdRWm_Restore(CARDFileInfo*, void*, u32) { +s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) { /* Nonmatching */ + s32 ret; + card_savedata* save; + card_savedata* save2; + BOOL needsWrite = FALSE; + BOOL invalid; + BOOL csum0a; + BOOL csum1a; + BOOL csum2a; + BOOL csum0b; + BOOL csum1b; + BOOL csum2b; + u64 serialNo; + + save = (card_savedata*)sTmpBuf; + save2 = (card_savedata*)sTmpBuf2; + ret = CARDRead(card, save, 0x2000, 0x2000); + if (ret != CARD_ERROR_READY) return ret; + csum0a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[0]); + csum1a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[1]); + csum2a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[2]); + ret = CARDRead(card, save2, 0x2000, 0x4000); + if (ret != CARD_ERROR_READY) return ret; + csum0b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[0]); + csum1b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[1]); + csum2b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[2]); + if (!csum0a && csum0b) { + memcpy(&save->gamedata[0], &save2->gamedata[0], sizeof(card_gamedata)); + needsWrite = TRUE; + } + if (!csum1a && csum1b) { + memcpy(&save->gamedata[1], &save2->gamedata[1], sizeof(card_gamedata)); + needsWrite = TRUE; + } + if (!csum2a && csum2b) { + memcpy(&save->gamedata[2], &save2->gamedata[2], sizeof(card_gamedata)); + needsWrite = TRUE; + } + + invalid = !csum0a && !csum1a && !csum2a && !csum0b && !csum1b && !csum2b; + if (!mDoMemCdRWm_CheckCardStat(card)) + return CARD_ERROR_FATAL_ERROR; + + if (needsWrite) { + ret = CARDWrite(card, save, 0x2000, 0x2000); + if (ret != CARD_ERROR_READY) return ret; + ret = CARDWrite(card, save, 0x2000, 0x4000); + if (ret != CARD_ERROR_READY) return ret; + memcpy(dst, save->gamedata, size); + sSaveCount = save->saveCount; + g_mDoMemCd_control.field_0x1690 = save->field_0x04; + if (!invalid && g_mDoMemCd_control.mCardCommand != NULL) { + ret = CARDRead(card, g_mDoMemCd_control.mCardCommand, 0x12000, 0x6000); + if (ret != CARD_ERROR_READY) return ret; + } + + serialNo; + CARDGetSerialNo(g_mDoMemCd_control.mCardSlot, &serialNo); + g_mDoMemCd_control.mCardSerialNo = serialNo; + } + + return CARD_ERROR_READY; } #if VERSION == VERSION_PAL @@ -237,7 +300,7 @@ void mDoMemCdRWm_SetCheckSumPictData(u8* p) { } /* 8001A3D0-8001A408 .text mDoMemCdRWm_CalcCheckSumGameData__FPvUl */ -unsigned long long mDoMemCdRWm_CalcCheckSumGameData(void* p, u32 size) { +u64 mDoMemCdRWm_CalcCheckSumGameData(void* p, u32 size) { /* Nonmatching */ u32 c0 = 0, c1 = 0; for (int i = 0; i < size; i++) { @@ -245,7 +308,7 @@ unsigned long long mDoMemCdRWm_CalcCheckSumGameData(void* p, u32 size) { c0 += v; c1 += ~v; } - return ((unsigned long long)c0 << 32) | c1; + return ((u64)c0 << 32) | c1; } /* 8001A408-8001A454 .text mDoMemCdRWm_TestCheckSumGameData__FPv */