From d71cf42416932357f3723c10f2df8ea151404a16 Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Wed, 2 Oct 2024 19:22:51 -0400 Subject: [PATCH] m_Do_MemCardRWmng OK --- configure.py | 2 +- include/m_Do/m_Do_MemCard.h | 18 +++++- src/m_Do/m_Do_MemCard.cpp | 2 +- src/m_Do/m_Do_MemCardRWmng.cpp | 110 +++++++++++++++++++++++++-------- 4 files changed, 103 insertions(+), 29 deletions(-) diff --git a/configure.py b/configure.py index 2aac69740..1bd68a638 100644 --- a/configure.py +++ b/configure.py @@ -331,7 +331,7 @@ def JSystemLib(lib_name, objects, progress_category="third_party"): Object(Matching, "m_Do/m_Do_dvd_thread.cpp"), Object(Matching, "m_Do/m_Do_DVDError.cpp"), Object(Matching, "m_Do/m_Do_MemCard.cpp"), - Object(NonMatching, "m_Do/m_Do_MemCardRWmng.cpp"), + Object(Matching, "m_Do/m_Do_MemCardRWmng.cpp"), Object(Matching, "m_Do/m_Do_gba_com.cpp"), Object(Matching, "m_Do/m_Do_machine_exception.cpp"), ], diff --git a/include/m_Do/m_Do_MemCard.h b/include/m_Do/m_Do_MemCard.h index 288e2c602..ddb4c4018 100644 --- a/include/m_Do/m_Do_MemCard.h +++ b/include/m_Do/m_Do_MemCard.h @@ -52,12 +52,20 @@ class mDoMemCd_Ctrl_c { void setPictDataPtr(u8* v) { mPictDataPtr = v; } void setCardSerialNo(u64 v) { mCardSerialNo = v; } void setDataVersion(u32 v) { mDataVersion = v; } + u8 getCopyToPos() { return mCopyToPos; } + void setCopyToPos(u8 pos) { mCopyToPos = pos; } + + void clearProbeStat() {} + void getCardSerialNo() {} + void getDataVersion() {} + void getProbeStat() {} + void setPictWriteDataPtr(u8*) {} /* 0x0000 */ u8 mData[0x1650]; /* 0x1650 */ u8* mPictDataPtr; /* 0x1654 */ u8* mPictDataWritePtr; /* 0x1658 */ u8 mCardSlot; - /* 0x1659 */ u8 field_0x1659; + /* 0x1659 */ u8 mCopyToPos; /* 0x165A */ u8 field_0x165A; /* 0x165B */ u8 field_0x165B; /* 0x165C */ s32 mCommand; @@ -110,4 +118,12 @@ inline u8* mDoMemCd_getPictWriteDataPtr() { return g_mDoMemCd_control.getPictWriteDataPtr(); } +inline u8 mDoMemCd_getCopyToPos() { + return g_mDoMemCd_control.getCopyToPos(); +} + +inline void mDoMemCd_setCopyToPos(u8 pos) { + g_mDoMemCd_control.setCopyToPos(pos); +} + #endif /* M_DO_M_DO_MEMCARD_H */ diff --git a/src/m_Do/m_Do_MemCard.cpp b/src/m_Do/m_Do_MemCard.cpp index 9074c2a23..97b1af078 100644 --- a/src/m_Do/m_Do_MemCard.cpp +++ b/src/m_Do/m_Do_MemCard.cpp @@ -26,7 +26,7 @@ void mDoMemCd_Ctrl_c::ThdInit() { CARDInit(); mPictDataPtr = NULL; mPictDataWritePtr = NULL; - field_0x1659 = 0; + mCopyToPos = 0; field_0x165A = 2; field_0x1660 = CARD_NO_COMMAND; mCommand = CARD_NO_COMMAND; diff --git a/src/m_Do/m_Do_MemCardRWmng.cpp b/src/m_Do/m_Do_MemCardRWmng.cpp index 7ff49b7b1..68a97470e 100644 --- a/src/m_Do/m_Do_MemCardRWmng.cpp +++ b/src/m_Do/m_Do_MemCardRWmng.cpp @@ -45,14 +45,12 @@ struct card_savedata u32 csum; }; -static u8 sTmpBuf[0x2000]; -static u8 sTmpBuf2[0x2000]; +static u8 sTmpBuf[0x2000] ALIGN_DECL(32); +static u8 sTmpBuf2[0x2000] ALIGN_DECL(32); static u32 sSaveCount; /* 80019940-80019CE8 .text mDoMemCdRWm_Store__FP12CARDFileInfoPvUl */ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { - /* Nonmatching */ - s32 ret; mDoMemCdRWm_BuildHeader((mDoMemCdRWm_HeaderData*)sTmpBuf); ret = CARDWrite(card, sTmpBuf, 0x2000, 0x0000); @@ -71,7 +69,11 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { card_savedata* save = (card_savedata*)sTmpBuf; save->dataVersion = 0; memcpy(save->gamedata, data, size); +#if VERSION != VERSION_PAL save->saveCount = ++sSaveCount; +#else + save->saveCount = dComIfGs_getPalLanguage(); +#endif s32 csum = mDoMemCdRWm_CalcCheckSum(save, 0x1FFC); save->csum = csum; @@ -87,12 +89,13 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { if (ret != CARD_ERROR_READY) return ret; if (mDoMemCdRWm_CalcCheckSum(sTmpBuf, 0x1FFC) != csum) return ret; + s32 i; + u32 slot; if (mDoMemCd_getPictWriteDataPtr() != NULL) { - // mDoMemCd_getCopyToPos ? - if (g_mDoMemCd_control.field_0x1659 < 3) { - u32 slot = g_mDoMemCd_control.field_0x1659 * 3 + 3; + if (mDoMemCd_getCopyToPos() < 3) { + slot = mDoMemCd_getCopyToPos() * 3 + 3; u8* picData = mDoMemCd_getPictWriteDataPtr(); - for (s32 i = 0; i < 3; i++, picData += 0x2000) { + for (i = 0; i < 3; i++, picData += 0x2000) { ret = CARDWrite(card, picData, 0x2000, (slot + i) * 0x2000); if (ret != CARD_ERROR_READY) return ret; ret = CARDRead(card, sTmpBuf, 0x2000, (slot + i) * 0x2000); @@ -101,8 +104,8 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { } } } else { - u32 slot = dComIfGs_getDataNum() * 3 + 3; - for (s32 i = 0; i < 3; i++) { + slot = dComIfGs_getDataNum() * 3 + 3; + for (i = 0; i < 3; i++) { if (dComIfGp_isPictureFlag(i)) { memset(sTmpBuf, 0, 0x2000); JKRAramToMainRam(dComIfGp_getPictureBoxData(i), sTmpBuf, 0x2000); @@ -120,12 +123,11 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) { /* 80019CE8-80019F4C .text mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl */ s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) { - /* Nonmatching */ s32 ret; - card_savedata* save; - card_savedata* save2; BOOL needsWrite = FALSE; BOOL invalid; + card_savedata* save; + card_savedata* save2; BOOL csum0a; BOOL csum1a; BOOL csum2a; @@ -150,7 +152,7 @@ s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) { memcpy(&save->gamedata[0], &save2->gamedata[0], sizeof(card_gamedata)); needsWrite = TRUE; } - if (!csum1a && csum1b) { + if (!csum1a && csum2b) { // TODO: is this a bug? typo for `!csum1a && csum1b`? memcpy(&save->gamedata[1], &save2->gamedata[1], sizeof(card_gamedata)); needsWrite = TRUE; } @@ -159,7 +161,10 @@ s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) { needsWrite = TRUE; } - invalid = !csum0a && !csum1a && !csum2a && !csum0b && !csum1b && !csum2b; + invalid = FALSE; + if (!csum0a && !csum0b && !csum1a && !csum1b && !csum2a && !csum2b) { + invalid = TRUE; + } if (!mDoMemCdRWm_CheckCardStat(card)) return CARD_ERROR_FATAL_ERROR; @@ -168,34 +173,87 @@ s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) { 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; - mDoMemCd_setDataVersion(save->dataVersion); - if (!invalid && mDoMemCd_getPictDataPtr() != NULL) { - ret = CARDRead(card, mDoMemCd_getPictDataPtr(), 0x12000, 0x6000); - if (ret != CARD_ERROR_READY) return ret; - } + } - CARDGetSerialNo(mDoMemCd_getNowSlot(), &serialNo); - mDoMemCd_setCardSerialNo(serialNo); + memcpy(dst, save->gamedata, size); +#if VERSION != VERSION_PAL + sSaveCount = save->saveCount; +#else + if (save->saveCount > 4) { + g_mDoMemCd_control.field_0x165B = 0; + } else { + // TODO: does save->saveCount have the language index in it on PAL? + g_mDoMemCd_control.field_0x165B = save->saveCount; + } +#endif + mDoMemCd_setDataVersion(save->dataVersion); + if (!invalid && mDoMemCd_getPictDataPtr() != NULL) { + ret = CARDRead(card, mDoMemCd_getPictDataPtr(), 0x12000, 0x6000); + if (ret != CARD_ERROR_READY) return ret; } + CARDGetSerialNo(mDoMemCd_getNowSlot(), &serialNo); + mDoMemCd_setCardSerialNo(serialNo); + return CARD_ERROR_READY; } #if VERSION == VERSION_PAL -s32 mDoMemCdRWm_Restore2(CARDFileInfo*) { - /* Nonmatching */ +s32 mDoMemCdRWm_Restore2(CARDFileInfo* card) { + s32 ret; + card_savedata* save; + save = (card_savedata*)sTmpBuf; + ret = CARDRead(card, save, 0x2000, 0x2000); + if (ret != CARD_ERROR_READY) { + ret = CARDRead(card, save, 0x2000, 0x4000); + if (ret != CARD_ERROR_READY) return ret; + } + + if (save->saveCount > 4) { + g_mDoMemCd_control.field_0x165B = 0; + } else { + // TODO: does save->saveCount have the language index in it on PAL? + g_mDoMemCd_control.field_0x165B = save->saveCount; + } + + return CARD_ERROR_READY; } #endif /* 80019F4C-8001A0A8 .text mDoMemCdRWm_BuildHeader__FP22mDoMemCdRWm_HeaderData */ void mDoMemCdRWm_BuildHeader(mDoMemCdRWm_HeaderData* header) { +#if VERSION == VERSION_JPN + snprintf(header->comment, sizeof(header->comment), "ゼルダの伝説~風のタクト~"); +#else snprintf(header->comment, sizeof(header->comment), "Zelda: The Wind Waker"); +#endif OSTime time = OSGetTime(); OSCalendarTime cal; OSTicksToCalendarTime(time, &cal); +#if VERSION == VERSION_JPN + snprintf(header->info, sizeof(header->info), "%d月%d日のセーブデータです", cal.month + 1, cal.day_of_month); +#elif VERSION == VERSION_USA snprintf(header->info, sizeof(header->info), "%d/%d Save Data", cal.month + 1, cal.day_of_month); +#else + switch (dComIfGs_getPalLanguage()) { + case 0: + snprintf(header->info, sizeof(header->info), "%d/%d Save Data", cal.month + 1, cal.day_of_month); + break; + case 1: + snprintf(header->info, sizeof(header->info), "%d/%d Spielstand", cal.day_of_month, cal.month + 1); + break; + case 2: + // Extended ASCII 0xE9 is: é + snprintf(header->info, sizeof(header->info), "Donn%ces de jeu %d/%d", 0xE9, cal.day_of_month, cal.month + 1); + break; + case 3: + snprintf(header->info, sizeof(header->info), "Datos guardados el %d/%d", cal.day_of_month, cal.month + 1); + break; + case 4: + snprintf(header->info, sizeof(header->info), "Dati salvati: %d/%d", cal.day_of_month, cal.month + 1); + break; + } +#endif mDoDvdThd_mountArchive_c* cmd = mDoDvdThd_mountArchive_c::create("/res/CardIcon/cardicon.arc", 0, NULL); while (!cmd->sync()) ; JKRArchive* arc = cmd->getArchive();