From acc077a24c4fc75b98ccdd30e47b45ee897bb236 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Wed, 16 Nov 2022 07:32:07 +0000 Subject: [PATCH] Mempak doc (#1382) * Mempak doc * Format * Suggested changes * Further changes --- include/functions.h | 8 -- include/mempak.h | 21 ++++ include/z64.h | 1 + src/code/db_camera.c | 30 +++--- src/code/mempak.c | 231 +++++++++++++++++++++++++++++-------------- src/code/padmgr.c | 14 +-- 6 files changed, 204 insertions(+), 101 deletions(-) create mode 100644 include/mempak.h diff --git a/include/functions.h b/include/functions.h index 3502a6dc96..5518cb2a92 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1395,14 +1395,6 @@ void DbCamera_Reset(Camera* cam, DbCamera* dbCam); // ? DbCamera_UpdateDemoControl(?); void func_800BB0A0(f32 u, Vec3f* pos, f32* roll, f32* viewAngle, f32* point0, f32* point1, f32* point2, f32* point3); s32 func_800BB2B4(Vec3f* pos, f32* roll, f32* fov, CutsceneCameraPoint* point, s16* keyFrame, f32* curFrame); -s32 Mempak_Init(s32 controllerNb); -s32 Mempak_GetFreeBytes(s32 controllerNb); -s32 Mempak_FindFile(s32 controllerNb, char start, char end); -s32 Mempak_Write(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size); -s32 Mempak_Read(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size); -s32 Mempak_Alloc(s32 controllerNb, char* idx, s32 size); -s32 Mempak_DeleteFile(s32 controllerNb, char idx); -s32 Mempak_GetFileSize(s32 controllerNb, char idx); void KaleidoManager_LoadOvl(KaleidoMgrOverlay* ovl); void KaleidoManager_ClearOvl(KaleidoMgrOverlay* ovl); void KaleidoManager_Init(PlayState* play); diff --git a/include/mempak.h b/include/mempak.h new file mode 100644 index 0000000000..767b3966d4 --- /dev/null +++ b/include/mempak.h @@ -0,0 +1,21 @@ +#ifndef MEMPAK_H +#define MEMPAK_H + +#include "ultra64.h" + +s32 Mempak_Init(s32 controllerNum); +s32 Mempak_GetFreeBytes(s32 controllerNum); +s32 Mempak_FindFiles(s32 controllerNum, char start, char end); +s32 Mempak_Write(s32 controllerNum, char letter, void* buffer, s32 offset, s32 size); +s32 Mempak_Read(s32 controllerNum, char letter, void* buffer, s32 offset, s32 size); +s32 Mempak_CreateFile(s32 controllerNum, char* letter, s32 size); +s32 Mempak_DeleteFile(s32 controllerNum, char letter); +s32 Mempak_GetFileSize(s32 controllerNum, char letter); + +// Converts a file letter to its numerical index +#define MEMPAK_LETTER_TO_INDEX(c) ((c) - 'A') + +// Converts a numerical index to a file letter +#define MEMPAK_INDEX_TO_LETTER(i) ((i) + 'A') + +#endif diff --git a/include/z64.h b/include/z64.h index 8cfcfd160b..40dabeb5e3 100644 --- a/include/z64.h +++ b/include/z64.h @@ -38,6 +38,7 @@ #include "fault.h" #include "sched.h" #include "rumble.h" +#include "mempak.h" #include "tha.h" #include "thga.h" diff --git a/src/code/db_camera.c b/src/code/db_camera.c index ce96764ecf..72ea7fd82a 100644 --- a/src/code/db_camera.c +++ b/src/code/db_camera.c @@ -1,4 +1,3 @@ -#include "ultra64.h" #include "global.h" #define DBCAM_CONTROLLER_PORT 2 @@ -1507,15 +1506,15 @@ static s32 sAllocSize; s32 DbCamera_GetFirstAvailableLetter(void) { s32 i; + for (i = 0; i < ARRAY_COUNT(sLetters); i++) { switch (sLetters[i]) { case 'O': break; default: - return 'A' + i; + return MEMPAK_INDEX_TO_LETTER(i); } } - return '?'; } @@ -1653,7 +1652,7 @@ s32 DbCamera_SaveCallback(char* c) { freeSize = Mempak_GetFreeBytes(DBCAM_CONTROLLER_PORT); if ((u32)sAllocSize < (freeSize + ret)) { - if (!Mempak_Alloc(DBCAM_CONTROLLER_PORT, c, sAllocSize)) { + if (!Mempak_CreateFile(DBCAM_CONTROLLER_PORT, c, sAllocSize)) { return false; } @@ -1867,7 +1866,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlToggleSwitch ^= 1; } - D_8012CEE0[41][9] = sCurFileIdx + 'A'; + D_8012CEE0[41][9] = MEMPAK_INDEX_TO_LETTER(sCurFileIdx); func_8006376C(0xA, 7, 5, D_8012CEE0[41]); func_8006376C(0x10, 7, 5, D_8012CF60[dbCamera->sub.demoCtrlActionIdx]); func_8006376C(0x14, 7, 5, D_8012CF88[0]); @@ -1891,7 +1890,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.demoCtrlMenu++; } else { dbCamera->sub.demoCtrlToggleSwitch ^= 1; - D_8012CF84[9] = sCurFileIdx + 'A'; + D_8012CF84[9] = MEMPAK_INDEX_TO_LETTER(sCurFileIdx); func_8006376C(0xD, 7, 5, D_8012CF88[-1]); // todo: find something better func_8006376C(0x12, 7, 5, D_8012CF80); func_8006376C(0xD, 9, dbCamera->sub.demoCtrlToggleSwitch ? 1 : 6, "PRESS B BUTTON"); @@ -1909,7 +1908,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { case DEMO_CTRL_MENU(ACTION_SAVE, MENU_CALLBACK): case DEMO_CTRL_MENU(ACTION_LOAD, MENU_CALLBACK): case DEMO_CTRL_MENU(ACTION_CLEAR, MENU_CALLBACK): { - D_8012CEE0[41][9] = sCurFileIdx + 'A'; + D_8012CEE0[41][9] = MEMPAK_INDEX_TO_LETTER(sCurFileIdx); func_8006376C(0xC, 7, 5, D_8012CEE0[41]); func_8006376C(0x12, 7, 5, D_8012CF60[dbCamera->sub.demoCtrlActionIdx]); func_8006376C(0x16, 7, 5, D_8012CF9C[0]); @@ -1927,7 +1926,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { case DEMO_CTRL_MENU(ACTION_LOAD, MENU_SUCCESS): case DEMO_CTRL_MENU(ACTION_CLEAR, MENU_SUCCESS): { dbCamera->sub.demoCtrlToggleSwitch ^= 1; - D_8012CEE0[41][9] = sCurFileIdx + 'A'; + D_8012CEE0[41][9] = MEMPAK_INDEX_TO_LETTER(sCurFileIdx); func_8006376C(0xD, 7, 5, D_8012CEE0[41]); func_8006376C(0x13, 7, 5, D_8012CF60[dbCamera->sub.demoCtrlMenu / 100]); func_8006376C(0x17, 7, 5, D_8012CFA4); @@ -1950,7 +1949,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { case DEMO_CTRL_MENU(ACTION_LOAD, MENU_ERROR): case DEMO_CTRL_MENU(ACTION_CLEAR, MENU_ERROR): { dbCamera->sub.demoCtrlToggleSwitch ^= 1; - D_8012CEE0[41][9] = sCurFileIdx + 'A'; + D_8012CEE0[41][9] = MEMPAK_INDEX_TO_LETTER(sCurFileIdx); func_8006376C(0xD, 7, 5, D_8012CEE0[(dbCamera->sub.demoCtrlMenu / 100) + 32]); func_8006376C(0x11, 7, 5, D_8012CFAC); func_8006376C(0x17, 7, 5, D_8012CFA4); @@ -1971,11 +1970,12 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { default: { if (Mempak_Init(DBCAM_CONTROLLER_PORT)) { - sMempakFiles = Mempak_FindFile(DBCAM_CONTROLLER_PORT, 'A', 'E'); + sMempakFiles = Mempak_FindFiles(DBCAM_CONTROLLER_PORT, 'A', 'E'); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_CALLBACK); DbCamera_CalcMempakAllocSize(); if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); + sMempakFilesize = + Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, MEMPAK_INDEX_TO_LETTER(sCurFileIdx)); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; @@ -1984,7 +1984,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { block_1: idx2 = 1; for (i = 0; i < 5; i++) { - sp74[i * 2 + 1] = (sMempakFiles & idx2) ? i + 'A' : '?'; + sp74[i * 2 + 1] = (sMempakFiles & idx2) ? MEMPAK_INDEX_TO_LETTER(i) : '?'; sp74[i * 2 + 0] = '-'; idx2 <<= 1; @@ -2002,7 +2002,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); + sMempakFilesize = + Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, MEMPAK_INDEX_TO_LETTER(sCurFileIdx)); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; @@ -2019,7 +2020,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); + sMempakFilesize = + Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, MEMPAK_INDEX_TO_LETTER(sCurFileIdx)); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; diff --git a/src/code/mempak.c b/src/code/mempak.c index 2ccf151351..4d00b311ab 100644 --- a/src/code/mempak.c +++ b/src/code/mempak.c @@ -1,184 +1,271 @@ +/** + * @file mempak.c + * + * This file implements an interface for a controller memory pak filesystem (pfs), with operations to create, delete, + * read, write and check the size of files, as well as obtain a listing of which files currently exist. + * + * Each file is assigned an uppercase ASCII letter as an identifier, the game name for each is marked as + * 'ZELDA DEMO TOOL', encoded according to the N64 Font Code described in section 26.3 of the N64 Programming Manual. + */ #include "global.h" +#define MEMPAK_MAX_FILES 11 + OSPfs sMempakPfsHandle; s32 sMempakFreeBytes; -s32 sMempakFiles[10]; +s32 sMempakFiles[MEMPAK_MAX_FILES]; u16 sMempakCompanyCode = 1; u32 sMempakGameCode = 1; -// "ZELDA DEMO TOOL " -u8 sMempakGameName[0x10] = { 0x33, 0x1E, 0x25, 0x1D, 0x1A, 0x0F, 0x1D, 0x1E, - 0x26, 0x28, 0x0F, 0x2D, 0x28, 0x28, 0x25, 0x0F }; -u8 sMempakExtName[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +// NCH is a heavily abbreviated "N64 font code CHaracter" +// Conversion from A-Z to N64 Font Code +#define NCH(c) ((c)-0x27) +// Conversion from spaces to N64 Font Code +#define NCH_SPC (0x0F) -s32 Mempak_Init(s32 controllerNb) { - OSMesgQueue* mq; +u8 sMempakGameName[PFS_FILE_NAME_LEN] = { + NCH('Z'), NCH('E'), NCH('L'), NCH('D'), NCH('A'), NCH_SPC, NCH('D'), NCH('E'), + NCH('M'), NCH('O'), NCH_SPC, NCH('T'), NCH('O'), NCH('O'), NCH('L'), NCH_SPC, +}; + +u8 sMempakExtName[PFS_FILE_EXT_LEN] = { 0 }; + +/** + * Initializes the memory pak filesystem for a memory pak in the controller plugged into the specified port. Subsequent + * memory pak operations will use the same controller port. + * + * @return true if the operation completed successfully, false otherwise + */ +s32 Mempak_Init(s32 controllerNum) { + OSMesgQueue* serialEventQueue; s32 pad; s32 ret = false; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); - if (!osPfsInitPak(mq, &sMempakPfsHandle, controllerNb)) { + if (osPfsInitPak(serialEventQueue, &sMempakPfsHandle, controllerNum) == 0) { ret = true; } osPfsFreeBlocks(&sMempakPfsHandle, &sMempakFreeBytes); - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); - + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); return ret; } -s32 Mempak_GetFreeBytes(s32 controllerNb) { +s32 Mempak_GetFreeBytes(s32 controllerNum) { return sMempakFreeBytes; } -s32 Mempak_FindFile(s32 controllerNb, char start, char end) { - OSMesgQueue* mq; +/** + * Checks if the files identified by letters between `start` and `end` (inclusive) exist on the memory pak. + * + * This must be called before performing any individual file operations. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param start Start file letter + * @param end End file letter (inclusive) + * @return a bitfield where set bits indicate that the file exists + */ +s32 Mempak_FindFiles(s32 controllerNum, char start, char end) { + OSMesgQueue* serialEventQueue; s32 error; - char idx; + char letter; u32 bit = 1; - s32 flag = 0; + s32 bits = 0; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); - for (idx = start; idx <= end; idx++) { - sMempakExtName[0] = idx - 0x27; + for (letter = start; letter <= end; letter++) { + sMempakExtName[0] = NCH(letter); error = osPfsFindFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName, - &sMempakFiles[idx - 'A']); + &sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)]); if (error == 0) { - flag |= bit; + bits |= bit; } else { - sMempakFiles[idx - 'A'] = -1; + sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)] = -1; } bit <<= 1; - osSyncPrintf("mempak: find '%c' (%d)\n", idx, error); + osSyncPrintf("mempak: find '%c' (%d)\n", letter, error); } - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); - osSyncPrintf("mempak: find '%c' - '%c' %02x\n", start, end, flag); - - return flag; + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); + osSyncPrintf("mempak: find '%c' - '%c' %02x\n", start, end, bits); + return bits; } -s32 Mempak_Write(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) { - OSMesgQueue* mq; +/** + * Writes data to the file identified with `letter`. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param letter Memory pak file letter, in the range 'A' to ('A' + MEMPAK_MAX_FILES) + * @param buffer Buffer containing data to write + * @param offset Offset into the file to write to + * @param size Size in bytes + * @return true if the operation completed successfully, false otherwise + */ +s32 Mempak_Write(s32 controllerNum, char letter, void* buffer, s32 offset, s32 size) { + OSMesgQueue* serialEventQueue; s32 error; s32 ret = false; s32 pad; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (size < sMempakFreeBytes) { - error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 1, offset, size, buffer); + error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)], PFS_WRITE, offset, + size, buffer); if (error == 0) { ret = true; } - osSyncPrintf("mempak: write %d byte '%c' (%d)->%d\n", size, idx, sMempakFiles[idx - 'A'], error); + osSyncPrintf("mempak: write %d byte '%c' (%d)->%d\n", size, letter, + sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)], error); } - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); - + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); return ret; } -s32 Mempak_Read(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) { - OSMesgQueue* mq; +/** + * Reads data from the file identified with `letter`. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param letter Memory pak file letter, in the range 'A' to ('A' + MEMPAK_MAX_FILES) + * @param buffer Buffer to read data into + * @param offset Offset into the file to read from + * @param size Size in bytes + * @return true if the operation completed successfully, false otherwise + */ +s32 Mempak_Read(s32 controllerNum, char letter, void* buffer, s32 offset, s32 size) { + OSMesgQueue* serialEventQueue; s32 error; s32 ret = false; s32 pad; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (size < sMempakFreeBytes) { - error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 0, offset, size, buffer); + error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)], PFS_READ, offset, + size, buffer); if (error == 0) { ret = true; } - osSyncPrintf("mempak: read %d byte '%c' (%d)<-%d\n", size, idx, sMempakFiles[idx - 'A'], error); + osSyncPrintf("mempak: read %d byte '%c' (%d)<-%d\n", size, letter, sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)], + error); } - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); return ret; } -s32 Mempak_Alloc(s32 controllerNb, char* idx, s32 size) { - OSMesgQueue* mq; +/** + * Creates a new file on the memory pak. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param letter Memory pak file letter, in the range 'A' to ('A' + MEMPAK_MAX_FILES). + * If this points to a valid file letter the new file will be created using that letter, otherwise it will create + * a file using the first free letter and return it through this argument. If no letters are free, the last letter + * ('A' + MEMPAK_MAX_FILES - 1) is used. + * @param size File size + * @return true if the operation completed successfully, false otherwise + */ +s32 Mempak_CreateFile(s32 controllerNum, char* letter, s32 size) { + OSMesgQueue* serialEventQueue; s32 error; - s32 ret = 0; + s32 ret = false; s32 i; s32 pad; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); + + if (*letter >= MEMPAK_INDEX_TO_LETTER(0) && *letter < MEMPAK_INDEX_TO_LETTER(MEMPAK_MAX_FILES)) { + // Create file with specific letter + + sMempakExtName[0] = NCH(*letter); + if (-1 == sMempakFiles[MEMPAK_LETTER_TO_INDEX(*letter)]) { + // File does not already exist - if (*idx >= 'A' && *idx < 'L') { - sMempakExtName[0] = *idx - 0x27; - if (-1 == sMempakFiles[*idx - 'A']) { error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, - sMempakExtName, size, &sMempakFiles[*idx - 'A']); + sMempakExtName, size, &sMempakFiles[MEMPAK_LETTER_TO_INDEX(*letter)]); if (error == 0) { - ret = 1; + ret = true; } - osSyncPrintf("mempak: alloc %d byte '%c' (%d)\n", size, *idx, error); + osSyncPrintf("mempak: alloc %d byte '%c' (%d)\n", size, *letter, error); } else { - sMempakExtName[0] = *idx - 0x27; + // File already exists, delete then alloc + + sMempakExtName[0] = NCH(*letter); if (osPfsDeleteFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName) == 0) { - ret = 1; + ret = true; } error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, - sMempakExtName, size, &sMempakFiles[*idx - 'A']); + sMempakExtName, size, &sMempakFiles[MEMPAK_LETTER_TO_INDEX(*letter)]); if (error == 0) { - ret |= 1; + ret |= true; } - osSyncPrintf("mempak: resize %d byte '%c' (%d)\n", size, *idx, error); + osSyncPrintf("mempak: resize %d byte '%c' (%d)\n", size, *letter, error); } } else { - for (i = 0; i < ARRAY_COUNT(sMempakFiles); i++) { + // Find first free letter and create a file identified by it + for (i = 0; i < MEMPAK_MAX_FILES - 1; i++) { if (sMempakFiles[i] == -1) { break; } } + *letter = MEMPAK_INDEX_TO_LETTER(i); - *idx = i + 'A'; - sMempakExtName[0] = *idx - 0x27; + sMempakExtName[0] = NCH(*letter); error = osPfsAllocateFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName, size, &sMempakFiles[i]); - osSyncPrintf("mempak: alloc %d byte '%c' (%d) with search\n", size, *idx, error); + osSyncPrintf("mempak: alloc %d byte '%c' (%d) with search\n", size, *letter, error); if (error == 0) { - ret = 1; + ret = true; } } - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); - + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); return ret; } -s32 Mempak_DeleteFile(s32 controllerNb, char idx) { - OSMesgQueue* mq; +/** + * Deletes the file identified with `letter`. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param letter Memory pak file letter, in the range 'A' to ('A' + MEMPAK_MAX_FILES) + * @return true if the operation completed successfully, false otherwise + */ +s32 Mempak_DeleteFile(s32 controllerNum, char letter) { + OSMesgQueue* serialEventQueue; s32 error; s32 ret = false; - mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); + serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); - sMempakExtName[0] = idx - 0x27; + sMempakExtName[0] = NCH(letter); error = osPfsDeleteFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName); if (error == 0) { ret = true; } - osSyncPrintf("mempak: delete '%c' (%d)\n", idx, error); - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); + osSyncPrintf("mempak: delete '%c' (%d)\n", letter, error); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); return ret; } -s32 Mempak_GetFileSize(s32 controllerNb, char idx) { - OSMesgQueue* mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); +/** + * Gets the size of the file identified with `letter`. + * + * @param controllerNum Unused, the controller used is that which was last passed to `Mempak_Init` + * @param letter Memory pak file letter, in the range 'A' to ('A' + MEMPAK_MAX_FILES) + * @return the size of the file, or 0 if the operation failed for any reason + */ +s32 Mempak_GetFileSize(s32 controllerNum, char letter) { + OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(&gPadMgr); OSPfsState state; - s32 error = osPfsFileState(&sMempakPfsHandle, sMempakFiles[idx - 'A'], &state); + s32 error = osPfsFileState(&sMempakPfsHandle, sMempakFiles[MEMPAK_LETTER_TO_INDEX(letter)], &state); s32 pad; - PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, serialEventQueue); if (error != 0) { return 0; diff --git a/src/code/padmgr.c b/src/code/padmgr.c index 6f882477d1..40b08150dc 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -31,13 +31,13 @@ #include "global.h" #include "terminal.h" -#define PADMGR_LOG(controllerNo, msg) \ - if (1) { \ - osSyncPrintf(VT_FGCOL(YELLOW)); \ - /* padmgr: Controller %d: %s */ \ - osSyncPrintf("padmgr: %dコン: %s\n", (controllerNo) + 1, (msg)); \ - osSyncPrintf(VT_RST); \ - } \ +#define PADMGR_LOG(controllerNum, msg) \ + if (1) { \ + osSyncPrintf(VT_FGCOL(YELLOW)); \ + /* padmgr: Controller %d: %s */ \ + osSyncPrintf("padmgr: %dコン: %s\n", (controllerNum) + 1, (msg)); \ + osSyncPrintf(VT_RST); \ + } \ (void)0 #define LOG_SEVERITY_NOLOG 0