/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "save/save.h" #include "save/savestreamdolphin.h" #include "util/memory.h" errorret_t saveStreamOpenReadDolphin(savestreamdolphin_t *p, bool_t *found) { if(!SAVE.platform.mounted) { *found = false; errorThrow("No memory card mounted"); } int32_t result; do { result = CARD_Open( SAVE_DOLPHIN_CHANNEL, SAVE_DOLPHIN_FILE_NAME, &p->cardFile ); } while(result == CARD_ERROR_BUSY); if(result == CARD_ERROR_NOFILE) { *found = false; p->position = 0; p->writing = false; errorOk(); } if(result < 0) { *found = false; errorThrow("Failed to open memory card file: %s (%d)", saveCardErrorStringDolphin(result), result ); } do { result = CARD_Read(&p->cardFile, p->buffer, SAVE_DOLPHIN_SECTOR_SIZE, 0); } while(result == CARD_ERROR_BUSY); CARD_Close(&p->cardFile); if(result < 0) { *found = false; errorThrow("Failed to read memory card data: %s (%d)", saveCardErrorStringDolphin(result), result ); } *found = true; p->position = 0; p->writing = false; errorOk(); } errorret_t saveStreamOpenWriteDolphin(savestreamdolphin_t *p) { if(!SAVE.platform.mounted) errorThrow("No memory card mounted"); memoryZero(p->buffer, SAVE_DOLPHIN_SECTOR_SIZE); p->position = 0; p->writing = true; errorOk(); } void saveStreamCloseDolphin(savestreamdolphin_t *p) { if(!p->writing) return; int32_t result; do { result = CARD_Open( SAVE_DOLPHIN_CHANNEL, SAVE_DOLPHIN_FILE_NAME, &p->cardFile ); } while(result == CARD_ERROR_BUSY); if(result == CARD_ERROR_NOFILE) { do { result = CARD_Create( SAVE_DOLPHIN_CHANNEL, SAVE_DOLPHIN_FILE_NAME, SAVE_DOLPHIN_SECTOR_SIZE, &p->cardFile ); } while(result == CARD_ERROR_BUSY); } do { result = CARD_Write(&p->cardFile, p->buffer, SAVE_DOLPHIN_SECTOR_SIZE, 0); } while(result == CARD_ERROR_BUSY); CARD_Close(&p->cardFile); } errorret_t saveStreamReadBytesDolphin( savestreamdolphin_t *p, void *buf, const size_t len ) { if(p->position + len > SAVE_DOLPHIN_SECTOR_SIZE) { errorThrow("Save stream read exceeds sector size"); } memoryCopy(buf, p->buffer + p->position, len); p->position += len; errorOk(); } errorret_t saveStreamWriteBytesDolphin( savestreamdolphin_t *p, const void *buf, const size_t len ) { if(p->position + len > SAVE_DOLPHIN_SECTOR_SIZE) { errorThrow("Save stream write exceeds sector size"); } memoryCopy(p->buffer + p->position, buf, len); p->position += len; errorOk(); } errorret_t saveStreamSeekDolphin(savestreamdolphin_t *p, const size_t pos) { if(pos >= SAVE_DOLPHIN_SECTOR_SIZE) { errorThrow("Save stream seek out of range"); } p->position = pos; errorOk(); } errorret_t saveStreamTellDolphin(savestreamdolphin_t *p, size_t *out) { *out = p->position; errorOk(); }