summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakaRikka <38417346+TakaRikka@users.noreply.github.com>2021-05-21 16:09:08 -0700
committerGitHub <noreply@github.com>2021-05-21 16:09:08 -0700
commit65dae72e1ee0ad38bdef3186e3e5991f91664360 (patch)
treebbc09742828826f42830d5e02f6ed9b7caf27547
parentb5083e06f15c15881f5f325b3f4f5247b9952445 (diff)
parenta8e25bc9e8d5ed2315ccc40bb5fe52dd10289a1c (diff)
Merge pull request #3 from zsrtp/card_deletion
Added Zephiles' CARDDelete functions
-rw-r--r--include/card.h8
-rw-r--r--include/card_internal.h27
-rw-r--r--src/card.c274
3 files changed, 150 insertions, 159 deletions
diff --git a/include/card.h b/include/card.h
index a38b0c3..2ce2329 100644
--- a/include/card.h
+++ b/include/card.h
@@ -3,6 +3,8 @@
#include <stdint.h>
+#define CARD_SLOT_A 0 // Memory card slot A
+#define CARD_SLOT_B 1 // Memory card slot B
#define CARD_FILENAME_MAX 32
#define CARD_ICON_MAX 8
@@ -27,7 +29,7 @@ enum CardError {
FatalError = -128
};
-typedef void (*CARDCallback)(int chan, int result);
+typedef void (*CARDCallback)(int32_t chn, int32_t result);
typedef struct CardInfo {
int32_t channel;
@@ -74,8 +76,8 @@ int32_t CARDCreate(int32_t channel, char* fileName, uint32_t size, CardInfo* fil
int32_t CARDProbeEx(int32_t channel, int32_t* memSize, int32_t* sectorSize);
int32_t CARDGetStatus(int32_t channel, int32_t file_number, CARDStat* stat);
int32_t CARDWrite(CardInfo* fileInfo, void* buf, int32_t length, int32_t offset);
-int32_t CARDDelete(int chan,char *fileName);
-int32_t CARDDeleteAsync(int chan,char *fileName,CARDCallback callback);
+int32_t CARDDelete(int32_t chn, const char* fileName);
+int32_t CARDDeleteAsync(int32_t chn, const char* fileName, CARDCallback callback);
#ifdef __cplusplus
}
#endif // __cplusplus
diff --git a/include/card_internal.h b/include/card_internal.h
new file mode 100644
index 0000000..237ac1d
--- /dev/null
+++ b/include/card_internal.h
@@ -0,0 +1,27 @@
+/*!
+ * This file contains the declaration of internal CARD functions and structures.
+ */
+#ifndef __CARD_INTERNAL_H__
+#define __CARD_INTERNAL_H__
+#include "card.h"
+#include <stddef.h>
+
+typedef struct CARDBlock {
+ uint8_t unk[0x110];
+} CARDBlock;
+
+// 0x8044cbc0 in US; Specifically have to use this one and not make a new one
+extern CARDBlock __CARDBlock[2]; // One for each memory card slot
+
+// Vanilla functions used in main code
+void __CARDDefaultApiCallback(int32_t chn, int32_t result);
+void __CARDSyncCallback(int32_t chn, int32_t result);
+int32_t __CARDGetControlBlock(int32_t chn, void** card);
+int32_t __CARDPutControlBlock(void* card, int32_t result);
+int32_t __CARDSync(int32_t chn);
+int32_t __CARDUpdateFatBlock(int32_t chn, void* fatBlock, CARDCallback callback);
+void* __CARDGetDirBlock(void* card);
+int32_t __CARDUpdateDir(int32_t chn, CARDCallback callback);
+int32_t __CARDAccess(void* card, void* dirBlock);
+
+#endif // __CARD_INTERNAL_H__ \ No newline at end of file
diff --git a/src/card.c b/src/card.c
index a981220..ff85643 100644
--- a/src/card.c
+++ b/src/card.c
@@ -1,179 +1,141 @@
#include "card.h"
-#include <string.h>
+#include "card_internal.h"
+#include <stddef.h>
-int __CARDUpdateFatBlock(int param_1, short *param_2, CARDCallback param_3);
-int __CARDPutControlBlock(int *param_1, int param_2);
-char* __CARDGetDirBlock(int param_1);
-void __CARDSyncCallback(int chan, int result);
-void __CARDDefaultApiCallback(int chan, int result);
-int __CARDGetControlBlock(int param_1,int **param_2);
-int __CARDUpdateDir(int param_1, CARDCallback param_2);
-int __CARDSync(int param_1);
+// We declare those instead of using the standard headers to let
+// the linker link them against the ones already in the game's code.
+int32_t strncmp(const char* str1, const char* str2, size_t n);
+void* memset(void* dst, int val, size_t n);
-extern char* __CARDBlock;
+// +=-=-=-=-=-=-=-=-=-=-=+
+// | Deletion functions |
+// +=-=-=-=-=-=-=-=-=-=-=+
-int __CARDIsOpened() {
- return 0;
-}
-
-int __CARDFreeBlock(int param_1, uint16_t param_2, CARDCallback param_3)
-{
- uint32_t uVar1;
- int iVar2;
- short *psVar3;
-
- if (__CARDBlock[param_1 * 0x44] == 0) {
- iVar2 = -3;
+int32_t __CARDFreeBlock(int32_t chn, uint16_t block, CARDCallback callback) {
+ uint32_t card = (uint32_t)(&__CARDBlock[chn]);
+ if (*(int32_t*)card == 0) {
+ return NoCard;
}
- else {
- psVar3 = (short *)*((int *)__CARDBlock + param_1 * 0x44 + 0x22);
- while (param_2 != 0xffff) {
- uVar1 = (uint32_t)param_2;
- if ((param_2 < 5) || (*(uint16_t *)(__CARDBlock + param_1 * 0x44 + 4) <= uVar1)) {
- return -6;
- }
- param_2 = psVar3[uVar1];
- psVar3[uVar1] = 0;
- psVar3[3] = psVar3[3] + 1;
+
+ uint16_t cardVar = *(uint16_t*)(card + 0x10); // Maximum number of blocks?
+ uint16_t* fatBlock = *(uint16_t**)(card + 0x88);
+
+ while (block != 0xFFFF) {
+ uint32_t tempBlock = (uint32_t)block;
+ if ((tempBlock < 5) || (tempBlock >= cardVar)) {
+ return Broken;
}
- iVar2 = __CARDUpdateFatBlock(param_1,psVar3,param_3);
+
+ block = fatBlock[tempBlock];
+ fatBlock[tempBlock] = 0;
+ fatBlock[3] += 1;
}
- return iVar2;
+
+ return __CARDUpdateFatBlock(chn, fatBlock, callback);
}
-void DeleteCallback(int param_1,int param_2)
-{
- CARDCallback pcVar1;
-
- pcVar1 = (CARDCallback)*((int *)__CARDBlock + param_1 * 0x44 + 0x34);
- __CARDBlock[param_1 * 0x44 + 0x34] = 0;
- if (((param_2 < 0) ||
- (param_2 = __CARDFreeBlock(param_1,*(uint16_t *)((int)__CARDBlock + param_1 * 0x110 + 0xbe), pcVar1), param_2 < 0)) &&
- (__CARDPutControlBlock((int*)__CARDBlock + param_1 * 0x44,param_2), pcVar1 != (CARDCallback)0x0)) {
- (*pcVar1)(param_1,param_2);
+void DeleteCallback(int32_t chn, int32_t result) {
+ uint32_t card = (uint32_t)(&__CARDBlock[chn]);
+ CARDCallback* cardApiCbAddress = (CARDCallback*)(card + 0xD0);
+ CARDCallback cb = *cardApiCbAddress;
+ *cardApiCbAddress = (CARDCallback)NULL;
+
+ int32_t ret = result;
+ if (ret >= Ready) {
+ uint16_t* currFileBlockAddr = (uint16_t*)(card + 0xBE);
+
+ ret = __CARDFreeBlock(chn, *currFileBlockAddr, cb);
+ if (ret >= Ready) {
+ return;
+ }
+ }
+
+ __CARDPutControlBlock((void*)card, ret);
+
+ if (cb) {
+ cb(chn, ret);
}
- return;
}
-int __CARDGetFileNo(int *param_1,char *param_2,int *param_3)
-{
- char cVar1;
- char cVar2;
- unsigned char bVar3;
- int iVar4;
- int iVar5;
- char *pcVar6;
- char *pcVar7;
- char *__s2;
- char *__s1;
-
- if (*param_1 == 0) {
- iVar5 = NoCard;
+int32_t __CARDGetFileNo(void* card, const char* fileName, int32_t* fileNo) {
+ int32_t cardIsAttached = *(int32_t*)((uint32_t)card);
+ if (cardIsAttached == 0) {
+ return NoCard;
}
- else {
- __s1 = (char *)__CARDGetDirBlock((int)param_1);
- iVar5 = 0;
- do {
- __s2 = (char *)param_1[0x43];
- if (*__s1 == -1) {
- iVar4 = -4;
- }
- else {
- if ((__s2 == __CARDBlock + 0x88) ||
- ((iVar4 = memcmp(__s1,__s2,4), iVar4 == 0 &&
- (iVar4 = memcmp(__s1 + 4,__s2 + 1,2), iVar4 == 0)))) {
- iVar4 = 0;
- }
- else {
- iVar4 = -10;
- }
- }
- if (-1 < iVar4) {
- pcVar6 = __s1 + 8;
- iVar4 = 0x20;
- pcVar7 = param_2;
- do {
- iVar4 = iVar4 + -1;
- if (iVar4 < 0) {
- if (*pcVar7 == '\0') {
- bVar3 = 1;
- }
- else {
- bVar3 = 0;
- }
- goto LAB_802a49bc;
- }
- cVar1 = *pcVar6;
- pcVar6 = pcVar6 + 1;
- cVar2 = *pcVar7;
- pcVar7 = pcVar7 + 1;
- if (cVar1 != cVar2) {
- bVar3 = 0;
- goto LAB_802a49bc;
- }
- } while (cVar2 != '\0');
- bVar3 = 1;
-LAB_802a49bc:
- if (bVar3) {
- *param_3 = iVar5;
- return Ready;
- }
+
+ uint32_t dirBlock = (uint32_t)(__CARDGetDirBlock(card));
+
+ int32_t i;
+ for (i = 0; i < 127; i++)
+ {
+ uint8_t* currentDirBlock = (uint8_t*)(dirBlock + (i * 0x40));
+ const char* currentFileName = (const char*)(&currentDirBlock[0x8]);
+
+ if (strncmp(fileName, currentFileName, 32) == 0) {
+ if (__CARDAccess(card, currentDirBlock) >= Ready) {
+ *fileNo = i;
+ break;
}
- iVar5 = iVar5 + 1;
- __s1 = __s1 + 0x40;
- } while (iVar5 < 0x7f);
- iVar5 = NoFile;
+ }
}
- return iVar5;
+
+ if (i >= 127) {
+ return NoFile;
+ }
+
+ return Ready;
}
-int32_t CARDDeleteAsync(int chan,char *fileName,CARDCallback callback)
+int32_t CARDDeleteAsync(int32_t chn, const char* fileName, CARDCallback callback)
{
- CARDCallback pcVar1;
- int iVar2;
- char* pcVar2;
- void *__s;
- int local_1c;
- int *local_18 [3];
-
- iVar2 = __CARDGetControlBlock(chan,local_18);
- if (-1 < iVar2) {
- iVar2 = __CARDGetFileNo(local_18[0],fileName,&local_1c);
- if (iVar2 < 0) {
- iVar2 = __CARDPutControlBlock(local_18[0],iVar2);
- }
- else {
- iVar2 = __CARDIsOpened();
- if (iVar2 == Ready) {
- pcVar2 = __CARDGetDirBlock((int)local_18[0]);
- __s = (void *)(pcVar2 + local_1c * 0x40);
- *(uint16_t *)((int)local_18[0] + 0xbe) = *(uint16_t *)((int)__s + 0x36);
- memset(__s,0xff,0x40);
- pcVar1 = callback;
- if (callback == (CARDCallback )0x0) {
- pcVar1 = __CARDDefaultApiCallback;
- }
- *(CARDCallback *)(local_18[0] + 0x34) = pcVar1;
- iVar2 = __CARDUpdateDir(chan,DeleteCallback);
- if (iVar2 < 0) {
- __CARDPutControlBlock(local_18[0],iVar2);
- }
- }
- else {
- iVar2 = __CARDPutControlBlock(local_18[0],-1);
- }
- }
+ uint32_t card;
+ int32_t ret = __CARDGetControlBlock(chn, (void**)(&card));
+ if (ret < Ready) {
+ return ret;
+ }
+
+ int32_t fileNo;
+ ret = __CARDGetFileNo((void*)card, fileName, &fileNo);
+ if (ret < Ready) {
+ __CARDPutControlBlock((void*)card, ret);
+ return ret;
+ }
+
+ uint32_t dirBlock = (uint32_t)(__CARDGetDirBlock((void*)card));
+ uint32_t entry = dirBlock + (fileNo * 0x40);
+
+ uint16_t* blockAddr = (uint16_t*)(entry + 0x36);
+ uint16_t* currFileBlockAddr = (uint16_t*)(card + 0xBE);
+ *currFileBlockAddr = *blockAddr;
+
+ memset((void*)entry, -1, 0x40);
+
+ CARDCallback cb = callback;
+ if (!cb) {
+ cb = __CARDDefaultApiCallback;
+ }
+
+ CARDCallback* cardApiCbAddress = (CARDCallback*)(card + 0xD0);
+ *cardApiCbAddress = cb;
+
+ ret = __CARDUpdateDir(chn, DeleteCallback);
+ if (ret >= Ready) {
+ return ret;
}
- return iVar2;
+
+ __CARDPutControlBlock((void*)card, ret);
+ return ret;
}
-int32_t CARDDelete(int chan,char *fileName)
+int32_t CARDDelete(int32_t chn, const char* fileName)
{
- int iVar1;
-
- iVar1 = CARDDeleteAsync(chan,fileName,__CARDSyncCallback);
- if (-1 < iVar1) {
- iVar1 = __CARDSync(chan);
+ int32_t ret = CARDDeleteAsync(chn, fileName, __CARDSyncCallback);
+ if (ret >= Ready) {
+ ret = __CARDSync(chn);
}
- return iVar1;
-} \ No newline at end of file
+ return ret;
+}
+
+// +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
+// | Other functions go here... |
+// +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+