2022-10-10 19:44:11 +00:00
|
|
|
#ifndef _CMEMORYCARDDRIVER
|
|
|
|
#define _CMEMORYCARDDRIVER
|
|
|
|
|
|
|
|
#include "MetroidPrime/Player/CGameState.hpp"
|
|
|
|
|
2022-10-10 19:58:03 +00:00
|
|
|
#include "Kyoto/CMemoryCardSys.hpp"
|
|
|
|
|
|
|
|
#include "rstl/auto_ptr.hpp"
|
|
|
|
#include "rstl/pair.hpp"
|
2022-10-10 21:46:32 +00:00
|
|
|
#include "rstl/reserved_vector.hpp"
|
2022-10-10 19:58:03 +00:00
|
|
|
#include "rstl/single_ptr.hpp"
|
|
|
|
#include "rstl/vector.hpp"
|
|
|
|
|
2022-10-11 14:58:55 +00:00
|
|
|
class CMemoryInStream;
|
|
|
|
|
2022-10-10 21:46:32 +00:00
|
|
|
struct SMemoryCardFileInfo {
|
|
|
|
CMemoryCardSys::CardFileHandle x0_fileInfo;
|
|
|
|
|
|
|
|
rstl::string x14_name;
|
|
|
|
rstl::vector< u8 > x24_saveFileData;
|
|
|
|
rstl::vector< u8 > x34_saveData;
|
2022-10-10 22:53:28 +00:00
|
|
|
|
2022-10-10 21:46:32 +00:00
|
|
|
SMemoryCardFileInfo(int cardPort, const rstl::string& name);
|
|
|
|
SMemoryCardFileInfo(const SMemoryCardFileInfo& other)
|
|
|
|
: x0_fileInfo(other.x0_fileInfo)
|
|
|
|
, x14_name(other.x14_name)
|
|
|
|
, x24_saveFileData(other.x24_saveFileData)
|
2022-10-10 22:53:28 +00:00
|
|
|
, x34_saveData(other.x34_saveData) {}
|
2022-10-10 21:46:32 +00:00
|
|
|
|
|
|
|
ECardResult Open();
|
|
|
|
ECardResult Close();
|
2022-10-11 12:09:23 +00:00
|
|
|
EMemoryCardPort GetFileCardPort() const { return x0_fileInfo.slot; }
|
2022-10-11 11:37:01 +00:00
|
|
|
int GetFileNo() const; // { return x0_fileInfo.GetFileNo(); }
|
2022-10-10 21:46:32 +00:00
|
|
|
ECardResult StartRead();
|
|
|
|
ECardResult TryFileRead();
|
|
|
|
ECardResult FileRead();
|
|
|
|
ECardResult GetSaveDataOffset(u32& offOut) const;
|
|
|
|
};
|
2022-10-10 19:58:03 +00:00
|
|
|
|
2022-10-11 13:41:20 +00:00
|
|
|
struct SSaveHeader {
|
|
|
|
uint x0_version;
|
|
|
|
bool x4_savePresent[3];
|
|
|
|
|
|
|
|
SSaveHeader();
|
|
|
|
// : x0_version(0) {}
|
|
|
|
|
2022-10-11 14:58:55 +00:00
|
|
|
explicit SSaveHeader(CMemoryInStream& in);
|
|
|
|
|
|
|
|
void DoPut(CMemoryStreamOut& out) const;
|
2022-10-11 13:41:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SGameFileSlot {
|
2022-10-11 14:58:55 +00:00
|
|
|
rstl::reserved_vector<u8, 940> x0_saveBuffer;
|
2022-10-11 13:41:20 +00:00
|
|
|
CGameState::GameFileStateInfo x944_fileInfo;
|
|
|
|
|
|
|
|
SGameFileSlot();
|
2022-10-11 14:58:55 +00:00
|
|
|
explicit SGameFileSlot(CMemoryInStream& in);
|
|
|
|
|
2022-10-11 13:41:20 +00:00
|
|
|
void InitializeFromGameState();
|
2022-10-11 14:58:55 +00:00
|
|
|
void LoadGameState(int idx);
|
|
|
|
void DoPut(CMemoryStreamOut& w) const;
|
2022-10-11 13:41:20 +00:00
|
|
|
};
|
2022-10-11 14:58:55 +00:00
|
|
|
CHECK_SIZEOF(SGameFileSlot, 0x3d8)
|
2022-10-11 13:41:20 +00:00
|
|
|
|
2022-10-10 22:53:28 +00:00
|
|
|
enum EState {
|
|
|
|
kS_Initial = 0,
|
|
|
|
kS_Ready = 1,
|
|
|
|
kS_NoCard = 2,
|
|
|
|
kS_DriverClosed = 3,
|
|
|
|
kS_CardFormatted = 4,
|
|
|
|
kS_CardProbeDone = 5,
|
|
|
|
kS_CardMountDone = 6,
|
|
|
|
kS_CardCheckDone = 7,
|
|
|
|
kS_FileCreateDone = 8,
|
|
|
|
kS_FileCreateTransactionalDone = 9,
|
|
|
|
kS_FileWriteTransactionalDone = 10,
|
|
|
|
kS_FileAltDeleteTransactionalDone = 11,
|
|
|
|
kS_CardProbeFailed = 12,
|
|
|
|
kS_CardMountFailed = 13,
|
|
|
|
kS_CardCheckFailed = 14,
|
|
|
|
kS_FileDeleteBadFailed = 15,
|
|
|
|
kS_FileDeleteAltFailed = 16,
|
|
|
|
kS_FileBad = 17,
|
|
|
|
kS_FileCreateFailed = 18,
|
|
|
|
kS_FileWriteFailed = 19,
|
|
|
|
kS_FileCreateTransactionalFailed = 20,
|
|
|
|
kS_FileWriteTransactionalFailed = 21,
|
|
|
|
kS_FileAltDeleteTransactionalFailed = 22,
|
|
|
|
kS_FileRenameBtoAFailed = 23,
|
|
|
|
kS_CardFormatFailed = 24,
|
|
|
|
kS_CardProbe = 25,
|
|
|
|
kS_CardMount = 26,
|
|
|
|
kS_CardCheck = 27,
|
|
|
|
kS_FileDeleteBad = 28,
|
|
|
|
kS_FileRead = 29,
|
|
|
|
kS_FileDeleteAlt = 30,
|
|
|
|
kS_FileCreate = 31,
|
|
|
|
kS_FileWrite = 32,
|
|
|
|
kS_FileCreateTransactional = 33,
|
|
|
|
kS_FileWriteTransactional = 34,
|
|
|
|
kS_FileAltDeleteTransactional = 35,
|
|
|
|
kS_FileRenameBtoA = 36,
|
|
|
|
kS_CardFormat = 37
|
|
|
|
};
|
|
|
|
|
2022-10-10 19:44:11 +00:00
|
|
|
class CMemoryCardDriver {
|
|
|
|
public:
|
|
|
|
enum EError {
|
|
|
|
kE_OK,
|
|
|
|
kE_CardBroken,
|
|
|
|
kE_CardWrongCharacterSet,
|
|
|
|
kE_CardIOError,
|
|
|
|
kE_CardWrongDevice,
|
|
|
|
kE_CardFull,
|
|
|
|
kE_CardStillFull, /* After attempting alt-delete (if needed) */
|
|
|
|
kE_CardNon8KSectors,
|
|
|
|
kE_FileMissing,
|
|
|
|
kE_FileCorrupted
|
|
|
|
};
|
2022-10-10 21:46:32 +00:00
|
|
|
enum EFileState { kFS_Unknown, kFS_NoFile, kFS_File, kFS_BadFile };
|
2022-10-10 19:44:11 +00:00
|
|
|
|
2022-10-10 19:58:03 +00:00
|
|
|
private:
|
2022-10-11 12:09:23 +00:00
|
|
|
EMemoryCardPort x0_cardPort;
|
2022-10-10 19:58:03 +00:00
|
|
|
CAssetId x4_saveBanner;
|
|
|
|
CAssetId x8_saveIcon0;
|
|
|
|
CAssetId xc_saveIcon1;
|
|
|
|
EState x10_state;
|
|
|
|
EError x14_error;
|
2022-10-11 11:07:44 +00:00
|
|
|
uint x18_cardFreeBytes;
|
|
|
|
uint x1c_cardFreeFiles;
|
2022-10-10 21:46:32 +00:00
|
|
|
uint x20_fileTime;
|
2022-10-10 23:08:19 +00:00
|
|
|
long long x28_cardSerial;
|
2022-10-10 21:46:32 +00:00
|
|
|
rstl::reserved_vector< u8, 174 > x30_systemData;
|
|
|
|
rstl::reserved_vector< rstl::auto_ptr< SGameFileSlot >, 3 > xe4_fileSlots;
|
|
|
|
rstl::reserved_vector< rstl::pair< EFileState, SMemoryCardFileInfo >, 2 > x100_mcFileInfos;
|
2022-10-10 23:22:28 +00:00
|
|
|
int x194_fileIdx;
|
2022-10-11 12:09:23 +00:00
|
|
|
rstl::single_ptr< CCardFileInfo > x198_fileInfo;
|
2022-10-10 19:58:03 +00:00
|
|
|
bool x19c_;
|
|
|
|
bool x19d_importPersistent;
|
|
|
|
|
|
|
|
public:
|
2022-10-10 19:44:11 +00:00
|
|
|
static bool IsCardBusy(EState);
|
|
|
|
static bool IsCardWriting(EState);
|
2022-10-11 13:41:20 +00:00
|
|
|
CMemoryCardDriver(EMemoryCardPort cardPort, CAssetId saveBanner, CAssetId saveIcon0,
|
|
|
|
CAssetId saveIcon1, bool importPersistent);
|
2022-10-10 19:44:11 +00:00
|
|
|
void ClearFileInfo();
|
|
|
|
~CMemoryCardDriver();
|
|
|
|
void Update();
|
2022-10-10 23:02:10 +00:00
|
|
|
void HandleCardError(ECardResult result, EState state);
|
2022-10-10 22:53:28 +00:00
|
|
|
void UpdateMountCard(ECardResult);
|
|
|
|
void UpdateCardCheck(ECardResult);
|
|
|
|
void UpdateFileRead(ECardResult);
|
|
|
|
void UpdateFileDeleteAlt(ECardResult);
|
|
|
|
void UpdateFileDeleteBad(ECardResult);
|
|
|
|
void UpdateFileCreate(ECardResult);
|
|
|
|
void UpdateFileWrite(ECardResult);
|
|
|
|
void UpdateFileCreateTransactional(ECardResult);
|
|
|
|
void UpdateFileWriteTransactional(ECardResult);
|
|
|
|
void UpdateFileRenameBtoA(ECardResult);
|
2022-10-10 19:44:11 +00:00
|
|
|
void StartFileRenameBtoA();
|
|
|
|
void WriteBackupBuf();
|
2022-10-10 22:53:28 +00:00
|
|
|
void UpdateFileAltDeleteTransactional(ECardResult);
|
|
|
|
void UpdateCardFormat(ECardResult);
|
2022-10-10 19:44:11 +00:00
|
|
|
void StartCardProbe();
|
|
|
|
void UpdateCardProbe();
|
|
|
|
void StartMountCard();
|
|
|
|
void StartCardCheck();
|
|
|
|
void ClearError();
|
|
|
|
void CheckCardCapacity();
|
|
|
|
void NoCardFound();
|
|
|
|
void IndexFiles();
|
|
|
|
void StartFileDeleteBad();
|
2022-10-10 23:22:28 +00:00
|
|
|
void StartFileDeleteAlt();
|
|
|
|
void StartFileRead();
|
2022-10-10 19:44:11 +00:00
|
|
|
void StartFileCreate();
|
|
|
|
void StartFileWrite();
|
|
|
|
void StartFileCreateTransactional();
|
|
|
|
void StartFileWriteTransactional();
|
|
|
|
void StartFileDeleteAltTransactional();
|
|
|
|
void StartCardFormat();
|
|
|
|
void InitializeFileInfo();
|
|
|
|
void ReadFinished();
|
|
|
|
void EraseFileSlot(int);
|
|
|
|
void BuildNewFileSlot(int);
|
|
|
|
void BuildExistingFileSlot(int);
|
|
|
|
void ImportPersistentOptions();
|
|
|
|
void ExportPersistentOptions();
|
|
|
|
const CGameState::GameFileStateInfo* GetGameFileStateInfo(int);
|
|
|
|
bool GetCardFreeBytes();
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // _CMEMORYCARDDRIVER
|