mirror of
https://github.com/bfbbdecomp/bfbb.git
synced 2024-11-23 06:19:45 +00:00
More iSG memcard stuff (#364)
This commit is contained in:
parent
03c006619f
commit
35c306b277
@ -9,6 +9,7 @@ extern "C" {
|
||||
|
||||
void* memset(void*, int, size_t);
|
||||
void* memcpy(void*, const void*, size_t);
|
||||
int memcmp(const void* ptr1, const void* ptr2, size_t num);
|
||||
size_t strlen(const char*);
|
||||
char* strcpy(char* dest, const char* source);
|
||||
char* strncpy(char* dest, const char* source, size_t n);
|
||||
|
@ -167,26 +167,25 @@ typedef struct OSContext
|
||||
f64 psf[32];
|
||||
} OSContext;
|
||||
|
||||
|
||||
#define PAD_MAX_CONTROLLERS 4
|
||||
|
||||
#define PAD_BUTTON_LEFT 0x0001
|
||||
#define PAD_BUTTON_LEFT 0x0001
|
||||
#define PAD_BUTTON_RIGHT 0x0002
|
||||
#define PAD_BUTTON_DOWN 0x0004
|
||||
#define PAD_BUTTON_UP 0x0008
|
||||
#define PAD_TRIGGER_Z 0x0010
|
||||
#define PAD_TRIGGER_R 0x0020
|
||||
#define PAD_TRIGGER_L 0x0040
|
||||
#define PAD_BUTTON_A 0x0100
|
||||
#define PAD_BUTTON_B 0x0200
|
||||
#define PAD_BUTTON_X 0x0400
|
||||
#define PAD_BUTTON_Y 0x0800
|
||||
#define PAD_BUTTON_DOWN 0x0004
|
||||
#define PAD_BUTTON_UP 0x0008
|
||||
#define PAD_TRIGGER_Z 0x0010
|
||||
#define PAD_TRIGGER_R 0x0020
|
||||
#define PAD_TRIGGER_L 0x0040
|
||||
#define PAD_BUTTON_A 0x0100
|
||||
#define PAD_BUTTON_B 0x0200
|
||||
#define PAD_BUTTON_X 0x0400
|
||||
#define PAD_BUTTON_Y 0x0800
|
||||
#define PAD_BUTTON_START 0x1000
|
||||
|
||||
#define PAD_ERR_NONE 0
|
||||
#define PAD_ERR_NONE 0
|
||||
#define PAD_ERR_NO_CONTROLLER -1
|
||||
#define PAD_ERR_NOT_READY -2
|
||||
#define PAD_ERR_TRANSFER -3
|
||||
#define PAD_ERR_NOT_READY -2
|
||||
#define PAD_ERR_TRANSFER -3
|
||||
|
||||
typedef struct PADStatus
|
||||
{
|
||||
@ -238,6 +237,19 @@ void AXFreeVoice(_AXVPB*);
|
||||
void OSSetSoundMode(u32 mode);
|
||||
void VIWaitForRetrace();
|
||||
|
||||
#define CARD_FILENAME_MAX 32
|
||||
#define CARD_MAX_FILE 127
|
||||
#define CARD_ICON_MAX 8
|
||||
|
||||
typedef struct CARDFileInfo
|
||||
{
|
||||
/*0x00*/ s32 chan;
|
||||
/*0x04*/ s32 fileNo;
|
||||
/*0x08*/ s32 offset;
|
||||
/*0x0C*/ s32 length;
|
||||
/*0x10*/ u16 iBlock;
|
||||
} CARDFileInfo;
|
||||
|
||||
#define CARD_RESULT_UNLOCKED 1
|
||||
#define CARD_RESULT_READY 0
|
||||
#define CARD_RESULT_BUSY -1
|
||||
@ -256,9 +268,37 @@ void VIWaitForRetrace();
|
||||
#define CARD_RESULT_CANCELED -14
|
||||
#define CARD_RESULT_FATAL_ERROR -128
|
||||
|
||||
// CARDBios.h
|
||||
void CARDInit(void);
|
||||
s32 CARDUnmount(s32 chan);
|
||||
s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed);
|
||||
s32 CARDGetEncoding(s32 chan, u16* encode);
|
||||
s32 CARDGetSectorSize(s32 chan, u32* size);
|
||||
// CARDMount.h
|
||||
s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize);
|
||||
s32 CARDUnmount(s32 chan);
|
||||
// CARDCheck.h
|
||||
s32 CARDCheckEx(s32 chan, s32* xferBytes);
|
||||
// CARDStat.h
|
||||
typedef struct CARDStat
|
||||
{
|
||||
/*0x00*/ char fileName[CARD_FILENAME_MAX];
|
||||
/*0x20*/ u32 length;
|
||||
/*0x24*/ u32 time;
|
||||
/*0x28*/ u8 gameName[4];
|
||||
/*0x2C*/ u8 company[2];
|
||||
/*0x2E*/ u8 bannerFormat;
|
||||
/*0x30*/ u32 iconAddr;
|
||||
/*0x34*/ u16 iconFormat;
|
||||
/*0x36*/ u16 iconSpeed;
|
||||
/*0x38*/ u32 commentAddr;
|
||||
/*0x3C*/ u32 offsetBanner;
|
||||
/*0x40*/ u32 offsetBannerTlut;
|
||||
/*0x44*/ u32 offsetIcon[CARD_ICON_MAX];
|
||||
/*0x64*/ u32 offsetIconTlut;
|
||||
/*0x68*/ u32 offsetData;
|
||||
} CARDStat;
|
||||
// CARDRead.h
|
||||
s32 CARDRead(struct CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "isavegame.h"
|
||||
|
||||
#include "xMemMgr.h"
|
||||
|
||||
#include "iFile.h"
|
||||
#include "iSystem.h"
|
||||
#include "iTRC.h"
|
||||
|
||||
#include <dolphin.h>
|
||||
@ -197,6 +200,449 @@ static S32 iSG_mc_exists(S32 slot)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static S32 iSG_mc_tryRepair(st_ISG_MEMCARD_DATA* mcdata)
|
||||
{
|
||||
S32 result = 0;
|
||||
S32 rc = 0;
|
||||
s32 xferBytes = 0;
|
||||
|
||||
if (mcdata->unk_0 == 0)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
else if (mcdata->unk_12c)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
result = CARDCheckEx(mcdata->unk_4, &xferBytes);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
else if (result == CARD_RESULT_ENCODING)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result != CARD_RESULT_BROKEN)
|
||||
{
|
||||
mcdata->unk_12c = 1;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_mc_isformatted(st_ISG_MEMCARD_DATA* mcdata)
|
||||
{
|
||||
S32 result = 0;
|
||||
S32 rc = 0;
|
||||
s32 xferBytes = 0;
|
||||
|
||||
if (mcdata->unk_0 == 0)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else if (mcdata->unk_12c)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
result = CARDCheckEx(mcdata->unk_4, &xferBytes);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
else if (result == CARD_RESULT_BROKEN)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_mc_isGCcard(st_ISG_MEMCARD_DATA* mcdata, int* param2, int* param3)
|
||||
{
|
||||
S32 result = 0;
|
||||
S32 rc = 0;
|
||||
|
||||
s32 xferBytes = 0;
|
||||
u16 encoding = 0;
|
||||
s32 memSize = 0;
|
||||
s32 sectorSize = 0;
|
||||
|
||||
if (param2)
|
||||
{
|
||||
*param2 = 0;
|
||||
}
|
||||
|
||||
if (param3)
|
||||
{
|
||||
*param3 = 0;
|
||||
}
|
||||
|
||||
if (mcdata->unk_0 == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (mcdata->unk_12c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
result = CARDProbeEx(mcdata->unk_4, &memSize, §orSize);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
result = CARDCheckEx(mcdata->unk_4, &xferBytes);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
else if (result == CARD_RESULT_BROKEN)
|
||||
{
|
||||
rc = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result == CARD_RESULT_ENCODING)
|
||||
{
|
||||
rc = 3;
|
||||
if (param2)
|
||||
{
|
||||
*param2 = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
if (result == CARD_RESULT_ENCODING && param2)
|
||||
{
|
||||
*param2 = 1;
|
||||
}
|
||||
if (result == CARD_RESULT_IOERROR && param3)
|
||||
{
|
||||
*param3 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
result = CARDGetEncoding(mcdata->unk_4, &encoding);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY && encoding && param2)
|
||||
{
|
||||
*param2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_cubeicon_size(S32 param1, S32 param2);
|
||||
static S32 iSG_get_finfo(st_ISG_MEMCARD_DATA*, const char*);
|
||||
// PS2 signature:
|
||||
// static signed int iSG_isSpaceForFile(class st_ISG_MEMCARD_DATA* mcdata, S32 mcidx, S32 fsize,
|
||||
// char* dpath, char* fname, S32* bytesNeeded, S32* availOnDisk)
|
||||
static S32 iSG_isSpaceForFile(st_ISG_MEMCARD_DATA* mcdata, S32 param2, const char* param3,
|
||||
S32* param4, S32* param5, S32* param6)
|
||||
{
|
||||
S32 rc = 0;
|
||||
S32 result = 0;
|
||||
s32 byteNotUsed = 0;
|
||||
s32 filesNotUsed = 0;
|
||||
S32 len;
|
||||
|
||||
if (mcdata->unk_0 == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
len = iSG_cubeicon_size(mcdata->unk_4, mcdata->sectorSize);
|
||||
len = len + param2;
|
||||
// FIXME: fakematch: x + (n-1) & -x is the same as Round x up to next n
|
||||
len = -mcdata->sectorSize & len + mcdata->sectorSize - 1;
|
||||
|
||||
do
|
||||
{
|
||||
result = CARDFreeBlocks(mcdata->unk_4, &byteNotUsed, &filesNotUsed);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
if (param5)
|
||||
{
|
||||
*param5 = byteNotUsed / mcdata->sectorSize;
|
||||
}
|
||||
if (param4)
|
||||
{
|
||||
*param4 = len / mcdata->sectorSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param6)
|
||||
{
|
||||
*param6 = 1;
|
||||
}
|
||||
|
||||
if (iSG_get_finfo(mcdata, param3))
|
||||
{
|
||||
if (param6)
|
||||
{
|
||||
*param6 = *param6 - 1 & ~(*param6 - 1 >> 0x1f); // FIXME: Fakematch
|
||||
}
|
||||
if (len <= mcdata->unk_b0.length + byteNotUsed)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len <= byteNotUsed && filesNotUsed > 0)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_mc_mount(S32 slot);
|
||||
static bool iSG_mc_settgt(st_ISG_MEMCARD_DATA* mcdata, S32 slot)
|
||||
{
|
||||
if (iSG_mc_mount(slot))
|
||||
{
|
||||
mcdata->unk_0 = 1;
|
||||
mcdata->unk_4 = slot;
|
||||
|
||||
iSG_mc_tryRepair(mcdata);
|
||||
CARDGetSectorSize(slot, (u32*)&mcdata->sectorSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
mcdata->unk_0 = 0;
|
||||
}
|
||||
|
||||
return mcdata->unk_0 != 0;
|
||||
}
|
||||
|
||||
static S32 iSG_mc_fopen(st_ISG_MEMCARD_DATA*, const char*, int, en_ISG_IOMODE, en_ASYNC_OPERR*);
|
||||
static void iSG_mc_fclose(st_ISG_MEMCARD_DATA*);
|
||||
static S32 iSG_get_finfo(st_ISG_MEMCARD_DATA* mcdata, const char* param2)
|
||||
{
|
||||
S32 rc = 0;
|
||||
en_ASYNC_OPERR operr = ISG_OPERR_NONE;
|
||||
|
||||
if (iSG_mc_fopen(mcdata, param2, -1, ISG_IOMODE_READ, &operr))
|
||||
{
|
||||
rc = 1;
|
||||
memcpy(&mcdata->unk_b0, &mcdata->unk_20, sizeof(CARDStat));
|
||||
memcpy(&mcdata->unk_9c, &mcdata->unk_c, sizeof(CARDFileInfo));
|
||||
iSG_mc_fclose(mcdata);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_curKosher(CARDStat* stat, CARDFileInfo* info)
|
||||
{
|
||||
S32 rc = 1;
|
||||
|
||||
if ((stat->iconAddr < 1 || stat->iconAddr > 0x7fffffff) &&
|
||||
(stat->commentAddr < 1 || stat->commentAddr > 0x7fffffff))
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char stuff[0x200] = { 0 };
|
||||
sprintf(stuff, "SPONGEBOB:WHENROBOTSATTACK::RyanNeilDan");
|
||||
void* alloc = xMemPushTemp(0x5e00 + 0x1f);
|
||||
// align buf address to 32 bytes
|
||||
char* buf = (char*)((U32)alloc + 0x1f & ~0x1f);
|
||||
|
||||
S32 result;
|
||||
do
|
||||
{
|
||||
result = CARDRead(info, buf, 0x5e00, 0);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
if (memcmp(buf + 0x5a40, stuff, strlen(stuff) - 1))
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (memcmp(buf, "Battle for Bikini Bottom", strlen("Battle for Bikini Bottom") - 1))
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
xMemPopTemp(alloc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
static S32 iSG_mc_fdel(st_ISG_MEMCARD_DATA*, const char*);
|
||||
static S32 iSG_fileKosher(st_ISG_MEMCARD_DATA* mcdata, const char* param2, int param3, int* param4)
|
||||
{
|
||||
S32 rc = 0;
|
||||
en_ASYNC_OPERR operr = ISG_OPERR_NONE;
|
||||
|
||||
if (param4)
|
||||
{
|
||||
*param4 = 0;
|
||||
}
|
||||
|
||||
if (iSG_mc_fopen(mcdata, param2, -1, ISG_IOMODE_READ, &operr) == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
S32 ret = iSG_curKosher(&mcdata->unk_20, &mcdata->unk_c);
|
||||
iSG_mc_fclose(mcdata);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
rc = 0;
|
||||
if (param3 && iSG_mc_fdel(mcdata, param2) && param4)
|
||||
{
|
||||
*param4 = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_get_fsize(st_ISG_MEMCARD_DATA* mcdata, const char* param2)
|
||||
{
|
||||
S32 rc = -1;
|
||||
|
||||
if (iSG_get_finfo(mcdata, param2))
|
||||
{
|
||||
rc = mcdata->unk_b0.length;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static S32 iSG_get_fmoddate(st_ISG_MEMCARD_DATA* mcdata, const char* fname, int* sec, int* min,
|
||||
int* hr, int* mon, int* day, int* yr)
|
||||
{
|
||||
S32 rc = 1;
|
||||
OSCalendarTime time = { 0 };
|
||||
|
||||
if (iSG_get_finfo(mcdata, fname) == 0)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: This first param isn't right, can't decipher the 64 bit math
|
||||
OSTicksToCalendarTime((u64)mcdata->unk_b0.time * (u64)(GET_BUS_FREQUENCY() / 4), &time);
|
||||
|
||||
if (sec)
|
||||
{
|
||||
*sec = time.sec;
|
||||
}
|
||||
if (min)
|
||||
{
|
||||
*min = time.min;
|
||||
}
|
||||
if (hr)
|
||||
{
|
||||
*hr = time.hour;
|
||||
}
|
||||
if (mon)
|
||||
{
|
||||
*mon = time.mon + 1;
|
||||
}
|
||||
if (day)
|
||||
{
|
||||
*day = time.mday;
|
||||
}
|
||||
if (mon)
|
||||
{
|
||||
*mon = time.mon + 1;
|
||||
}
|
||||
if (day)
|
||||
{
|
||||
*day = time.mday;
|
||||
}
|
||||
if (yr)
|
||||
{
|
||||
*yr = time.year;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void iSG_timestamp(CARDStat*)
|
||||
{
|
||||
}
|
||||
|
||||
static S32 iSG_cubeicon_size(S32 slot, S32 param2)
|
||||
{
|
||||
if ((U32)slot > 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// FIXME: fakematch: x + (n-1) & -x is the same as Round x up to next n
|
||||
S32 t = (param2 + 0x1ffU) & -param2;
|
||||
return -t & (t + 0x5c3f);
|
||||
}
|
||||
|
||||
static S32 iSG_chk_icondata()
|
||||
{
|
||||
return 1;
|
||||
@ -225,25 +671,24 @@ static void iSG_discard_icondata()
|
||||
|
||||
static S32 iSG_mc_unmount(S32 slot)
|
||||
{
|
||||
S32 ret = 0;
|
||||
s32 chan = slot;
|
||||
S32 rc = 0;
|
||||
S32 result;
|
||||
|
||||
do
|
||||
{
|
||||
result = CARDUnmount(chan);
|
||||
result = CARDUnmount(slot);
|
||||
} while (result == CARD_RESULT_BUSY);
|
||||
|
||||
if (result == CARD_RESULT_READY)
|
||||
{
|
||||
ret = 1;
|
||||
rc = 1;
|
||||
}
|
||||
else if (result == CARD_RESULT_NOCARD)
|
||||
{
|
||||
ret = 1;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void iSG_cb_asyndone(long, long)
|
||||
|
@ -3,28 +3,7 @@
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct sceMcStDateTime
|
||||
{
|
||||
U8 Resv2;
|
||||
U8 Sec;
|
||||
U8 Min;
|
||||
U8 Hour;
|
||||
U8 Day;
|
||||
U8 Month;
|
||||
U16 Year;
|
||||
};
|
||||
|
||||
struct sceMcTblGetDir
|
||||
{
|
||||
sceMcStDateTime _Create;
|
||||
sceMcStDateTime _Modify;
|
||||
U32 FileSizeByte;
|
||||
U16 AttrFile;
|
||||
U16 Reserve1;
|
||||
U32 Reserve2;
|
||||
U32 PdaAplNo;
|
||||
U8 EntryName[32];
|
||||
};
|
||||
#include <dolphin.h>
|
||||
|
||||
enum en_ISG_IOMODE
|
||||
{
|
||||
@ -131,7 +110,15 @@ public:
|
||||
struct st_ISG_MEMCARD_DATA
|
||||
{
|
||||
S32 unk_0;
|
||||
S32 unk_pad[75];
|
||||
S32 unk_4;
|
||||
S32 sectorSize;
|
||||
CARDFileInfo unk_c;
|
||||
CARDStat unk_20;
|
||||
S32 unk_pad5[4];
|
||||
CARDFileInfo unk_9c;
|
||||
CARDStat unk_b0;
|
||||
S32 unk_pad6[4];
|
||||
S32 unk_12c;
|
||||
};
|
||||
|
||||
#define ISG_NUM_SLOTS 2
|
||||
|
Loading…
Reference in New Issue
Block a user