prime/include/MetroidPrime/CMemoryCardDriver.hpp

203 lines
5.5 KiB
C++

#ifndef _CMEMORYCARDDRIVER
#define _CMEMORYCARDDRIVER
#include "MetroidPrime/Player/CGameState.hpp"
#include "Kyoto/CMemoryCardSys.hpp"
#include "rstl/auto_ptr.hpp"
#include "rstl/pair.hpp"
#include "rstl/reserved_vector.hpp"
#include "rstl/single_ptr.hpp"
#include "rstl/vector.hpp"
class CMemoryInStream;
struct SMemoryCardFileInfo {
CMemoryCardSys::CardFileHandle x0_fileInfo;
rstl::string x14_name;
rstl::vector< uchar > x24_saveFileData;
rstl::vector< char > x34_saveData;
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)
, x34_saveData(other.x34_saveData) {}
~SMemoryCardFileInfo() {}
ECardResult Open();
ECardResult Close();
CMemoryCardSys::EMemoryCardPort GetFileCardPort() const { return x0_fileInfo.slot; }
int GetFileNo() const; // { return x0_fileInfo.GetFileNo(); }
ECardResult StartRead();
ECardResult TryFileRead();
ECardResult FileRead();
ECardResult GetSaveDataOffset(u32& offOut) const;
};
struct SSaveHeader {
uint x0_version;
bool x4_savePresent[3];
explicit SSaveHeader(int);
explicit SSaveHeader(CMemoryInStream& in);
void PutTo(COutputStream& out) const;
};
struct SGameFileSlot {
rstl::reserved_vector<u8, 940> x0_saveBuffer;
CGameState::GameFileStateInfo x944_fileInfo;
SGameFileSlot();
explicit SGameFileSlot(CMemoryInStream& in);
void InitializeFromGameState();
void LoadGameState(int idx);
void PutTo(COutputStream& w) const;
};
CHECK_SIZEOF(SGameFileSlot, 0x3d8)
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
};
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
};
enum EFileState { kFS_Unknown, kFS_NoFile, kFS_File, kFS_BadFile };
struct SFileInfo {
EFileState first;
SMemoryCardFileInfo second;
SFileInfo(EFileState state, int cardPort, const rstl::string& name)
: first(state)
, second(cardPort, name)
{}
~SFileInfo();
};
private:
CMemoryCardSys::EMemoryCardPort x0_cardPort;
CAssetId x4_saveBanner;
CAssetId x8_saveIcon0;
CAssetId xc_saveIcon1;
EState x10_state;
EError x14_error;
uint x18_cardFreeBytes;
uint x1c_cardFreeFiles;
uint x20_fileTime;
long long x28_cardSerial;
rstl::reserved_vector< u8, 174 > x30_systemData;
rstl::reserved_vector< rstl::auto_ptr< SGameFileSlot >, 3 > xe4_fileSlots;
rstl::reserved_vector< SFileInfo, 2 > x100_mcFileInfos;
int x194_fileIdx;
rstl::single_ptr< CMemoryCardSys::CCardFileInfo > x198_fileInfo;
bool x19c_;
bool x19d_importPersistent;
public:
static bool IsCardBusy(EState);
static bool IsCardWriting(EState);
CMemoryCardDriver(CMemoryCardSys::EMemoryCardPort cardPort, CAssetId saveBanner, CAssetId saveIcon0,
CAssetId saveIcon1, bool importPersistent);
void ClearFileInfo();
~CMemoryCardDriver();
void Update();
void HandleCardError(ECardResult result, EState state);
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);
void StartFileRenameBtoA();
void WriteBackupBuf();
void UpdateFileAltDeleteTransactional(ECardResult);
void UpdateCardFormat(ECardResult);
void StartCardProbe();
void UpdateCardProbe();
void StartMountCard();
void StartCardCheck();
void ClearError();
void CheckCardCapacity();
void NoCardFound();
void IndexFiles();
void StartFileDeleteBad();
void StartFileDeleteAlt();
void StartFileRead();
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