diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2023-02-01 18:45:02 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2023-02-01 18:50:25 -0400 |
commit | 9fa0a7f1da1b70bee995f53c6c96c43189018772 (patch) | |
tree | 114548896790eaff23cdca84a025281de86bbb51 /src/Dolphin/card/CARDCreate.c | |
parent | 2ba3289286bbfcf9fcc13fd135d976058d8b6c2e (diff) |
global: Import Dolphin SDK
This version comes from the Metroid Prime decompilation project.
https://github.com/PrimeDecomp/prime
Diffstat (limited to 'src/Dolphin/card/CARDCreate.c')
-rw-r--r-- | src/Dolphin/card/CARDCreate.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/Dolphin/card/CARDCreate.c b/src/Dolphin/card/CARDCreate.c new file mode 100644 index 0000000..6802b91 --- /dev/null +++ b/src/Dolphin/card/CARDCreate.c @@ -0,0 +1,115 @@ +#include <dolphin/card.h> +#include <dolphin/dsp.h> +#include <dolphin/dvd.h> +#include <dolphin/os.h> + +#include <dolphin/CARDPriv.h> + +static void CreateCallbackFat(s32 chan, s32 result) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = 0; + if (result < 0) { + goto error; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[card->freeNo]; + memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); + memcpy(ent->company, card->diskID->company, sizeof(ent->company)); + ent->permission = CARD_ATTR_PUBLIC; + ent->copyTimes = 0; + ent->startBlock = card->startBlock; + + ent->bannerFormat = 0; + ent->iconAddr = 0xffffffff; + ent->iconFormat = 0; + ent->iconSpeed = 0; + ent->commentAddr = 0xffffffff; + + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + + card->fileInfo->offset = 0; + card->fileInfo->iBlock = ent->startBlock; + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) { + callback(chan, result); + } +} + +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, + CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16 fileNo; + u16 freeNo; + u16* fat; + + if (strlen(fileName) > (u32)CARD_FILENAME_MAX) { + return CARD_RESULT_NAMETOOLONG; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + if (size <= 0 || (size % card->sectorSize) != 0) { + return CARD_RESULT_FATAL_ERROR; + } + + freeNo = (u16)-1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) { + if (freeNo == (u16)-1) { + freeNo = fileNo; + } + } else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 && + __CARDCompareFileName(ent, fileName)) { + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + } + } + if (freeNo == (u16)-1) { + return __CARDPutControlBlock(card, CARD_RESULT_NOENT); + } + + fat = __CARDGetFatBlock(card); + if (card->sectorSize * fat[CARD_FAT_FREEBLOCKS] < size) { + return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->freeNo = freeNo; + ent = &dir[freeNo]; + ent->length = (u16)(size / card->sectorSize); + strncpy(ent->fileName, fileName, CARD_FILENAME_MAX); + + card->fileInfo = fileInfo; + fileInfo->chan = chan; + fileInfo->fileNo = freeNo; + + result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + return result; +} |