mirror of https://github.com/zeldaret/oot.git
				
				
				
			Mempak doc (#1382)
* Mempak doc * Format * Suggested changes * Further changes
This commit is contained in:
		
							parent
							
								
									6451fbc24f
								
							
						
					
					
						commit
						acc077a24c
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +38,7 @@
 | 
			
		|||
#include "fault.h"
 | 
			
		||||
#include "sched.h"
 | 
			
		||||
#include "rumble.h"
 | 
			
		||||
#include "mempak.h"
 | 
			
		||||
#include "tha.h"
 | 
			
		||||
#include "thga.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue