metaforce/Runtime/MP1/CMemoryCardDriver.hpp

217 lines
6.3 KiB
C++
Raw Normal View History

#ifndef __URDE_CMEMORYCARDDRIVER_HPP__
#define __URDE_CMEMORYCARDDRIVER_HPP__
#include "CMemoryCardSys.hpp"
2016-12-20 21:51:50 +00:00
#include "CGameState.hpp"
namespace urde
{
namespace MP1
{
class CMemoryCardDriver
{
friend class CSaveUI;
public:
enum class EState
{
2016-12-24 05:23:50 +00:00
Initial = 0,
2016-12-23 06:41:39 +00:00
Ready = 1,
NoCard = 2,
2016-12-24 05:23:50 +00:00
DriverClosed = 3,
2016-12-23 06:41:39 +00:00
CardFormatted = 4,
2016-12-24 05:23:50 +00:00
CardProbeDone = 5,
2016-12-23 06:41:39 +00:00
CardMountDone = 6,
2016-12-24 05:23:50 +00:00
CardCheckDone = 7,
FileCreateDone = 8,
FileCreateTransactionalDone = 9,
FileWriteTransactionalDone = 10,
FileDeleteAltTransactionalDone = 11,
CardProbeFailed = 12,
CardMountFailed = 13,
CardCheckFailed = 14,
FileDeleteBadFailed = 15,
FileDeleteAltFailed = 16,
FileBad = 17,
FileCreateFailed = 18,
FileWriteFailed = 19,
FileCreateTransactionalFailed = 20,
FileWriteTransactionalFailed = 21,
FileDeleteAltTransactionalFailed = 22,
FileRenameBtoAFailed = 23,
CardFormatFailed = 24,
CardProbe = 25,
2016-12-23 06:41:39 +00:00
CardMount = 26,
2016-12-24 05:23:50 +00:00
CardCheck = 27,
FileDeleteBad = 28,
FileRead = 29,
FileDeleteAlt = 30,
FileCreate = 31,
FileWrite = 32,
FileCreateTransactional = 33,
FileWriteTransactional = 34,
FileDeleteAltTransactional = 35,
FileRenameBtoA = 36,
2016-12-23 06:41:39 +00:00
CardFormat = 37
};
enum class EError
{
2016-12-24 05:23:50 +00:00
OK,
CardBroken,
CardWrongCharacterSet,
CardIOError,
CardWrongDevice,
CardFull,
CardStillFull, /* After attempting alt-delete (if needed) */
CardNon8KSectors,
FileMissing,
FileCorrupted
};
private:
2016-12-20 21:51:50 +00:00
struct SFileInfo
{
2016-12-28 08:51:28 +00:00
CMemoryCardSys::CardFileHandle x0_fileInfo;
std::string x14_name;
2016-12-20 21:51:50 +00:00
std::vector<u8> x24_saveFileData;
std::vector<u8> x34_saveData;
2016-12-28 08:51:28 +00:00
SFileInfo(kabufuda::ECardSlot cardPort, const std::string& name);
kabufuda::ECardResult Open();
kabufuda::ECardResult Close();
kabufuda::ECardSlot GetFileCardPort() const { return x0_fileInfo.slot; }
int GetFileNo() const { return x0_fileInfo->getFileNo(); }
kabufuda::ECardResult StartRead();
kabufuda::ECardResult TryFileRead();
kabufuda::ECardResult FileRead();
kabufuda::ECardResult GetSaveDataOffset(u32& offOut);
2016-12-20 21:51:50 +00:00
};
struct SSaveHeader
{
2016-12-24 00:45:51 +00:00
u32 x0_version = 0;
bool x4_savePresent[3];
void DoPut(CMemoryOutStream& out) const
{
out.writeUint32Big(x0_version);
for (int i=0 ; i<3 ; ++i)
out.writeBool(x4_savePresent[i]);
}
2016-12-20 21:51:50 +00:00
};
struct SGameFileSlot
{
u8 x0_saveBuffer[940] = {};
CGameState::GameFileStateInfo x944_fileInfo;
SGameFileSlot();
SGameFileSlot(CMemoryInStream& in);
2016-12-20 21:51:50 +00:00
void InitializeFromGameState();
2016-12-30 06:37:01 +00:00
void LoadGameState(u32 idx);
2016-12-24 00:45:51 +00:00
void DoPut(CMemoryOutStream& w) const
{
w.writeBytes(x0_saveBuffer, 940);
}
};
2016-12-24 05:23:50 +00:00
enum class EFileState
{
Unknown,
NoFile,
File,
BadFile
};
2016-12-28 08:51:28 +00:00
kabufuda::ECardSlot x0_cardPort;
ResId x4_saveBanner;
ResId x8_saveIcon0;
ResId xc_saveIcon1;
2016-12-23 06:41:39 +00:00
EState x10_state = EState::Initial;
2016-12-24 05:23:50 +00:00
EError x14_error = EError::OK;
s32 x18_cardFreeBytes = 0;
s32 x1c_cardFreeFiles = 0;
2016-12-20 21:51:50 +00:00
u32 x20_fileTime = 0;
u64 x28_cardSerial = 0;
2016-12-20 21:51:50 +00:00
u8 x30_systemData[174] = {};
std::unique_ptr<SGameFileSlot> xe4_fileSlots[3];
2016-12-24 05:23:50 +00:00
std::vector<std::pair<EFileState, SFileInfo>> x100_mcFileInfos;
2016-12-20 21:51:50 +00:00
u32 x194_fileIdx = -1;
2016-12-23 06:41:39 +00:00
std::unique_ptr<CMemoryCardSys::CCardFileInfo> x198_fileInfo;
bool x19c_ = false;
2016-12-30 06:37:01 +00:00
bool x19d_inGame;
public:
2016-12-28 08:51:28 +00:00
CMemoryCardDriver(kabufuda::ECardSlot cardPort, ResId saveBanner,
2016-12-30 06:37:01 +00:00
ResId saveIcon0, ResId saveIcon1, bool inGame);
2016-12-20 21:51:50 +00:00
2016-12-24 05:23:50 +00:00
void NoCardFound();
2016-12-30 06:37:01 +00:00
const CGameState::GameFileStateInfo* GetGameFileStateInfo(int idx);
2016-12-20 21:51:50 +00:00
static SSaveHeader LoadSaveHeader(CMemoryInStream& in);
static std::unique_ptr<SGameFileSlot> LoadSaveFile(CMemoryInStream& in);
void ReadFinished();
2016-12-23 06:41:39 +00:00
void ImportPersistentOptions();
void ExportPersistentOptions();
2016-12-20 21:51:50 +00:00
void CheckCardCapacity();
2016-12-24 05:23:50 +00:00
void IndexFiles();
void StartCardProbe(); // 25
void StartMountCard(); // 26
void StartCardCheck(); // 27
void StartFileDeleteBad(); // 28
void StartFileRead(); // 29
void StartFileDeleteAlt(); // 30
void StartFileCreate(); // 31
void StartFileWrite(); // 32
void StartFileCreateTransactional(); // 33
void StartFileWriteTransactional(); // 34
void StartFileDeleteAltTransactional(); // 35
void StartFileRenameBtoA(); // 36
void StartCardFormat(); // 37
void UpdateCardProbe(); // 25
2016-12-28 08:51:28 +00:00
void UpdateMountCard(kabufuda::ECardResult result); // 26
void UpdateCardCheck(kabufuda::ECardResult result); // 27
void UpdateFileDeleteBad(kabufuda::ECardResult result); // 28
void UpdateFileRead(kabufuda::ECardResult result); // 29
void UpdateFileDeleteAlt(kabufuda::ECardResult result); // 30
void UpdateFileCreate(kabufuda::ECardResult result); // 31
void UpdateFileWrite(kabufuda::ECardResult result); // 32
void UpdateFileCreateTransactional(kabufuda::ECardResult result); // 33
void UpdateFileWriteTransactional(kabufuda::ECardResult result); // 34
void UpdateFileDeleteAltTransactional(kabufuda::ECardResult result); // 35
void UpdateFileRenameBtoA(kabufuda::ECardResult result); // 36
void UpdateCardFormat(kabufuda::ECardResult result); // 37
2016-12-23 06:41:39 +00:00
void ClearFileInfo() { x198_fileInfo.reset(); }
2016-12-30 06:37:01 +00:00
void BuildNewFileSlot(u32 saveIdx);
2016-12-31 00:51:51 +00:00
void EraseFileSlot(u32 saveIdx);
2016-12-30 06:37:01 +00:00
void BuildExistingFileSlot(u32 saveIdx);
2016-12-23 06:41:39 +00:00
void InitializeFileInfo();
void WriteBackupBuf();
bool GetCardFreeBytes();
2016-12-28 08:51:28 +00:00
void HandleCardError(kabufuda::ECardResult result, EState state);
void Update();
2016-12-26 07:58:44 +00:00
void ClearError() { x14_error = EError::OK; }
2016-12-20 21:51:50 +00:00
2016-12-24 05:23:50 +00:00
static bool IsCardBusy(EState v)
2016-12-20 21:51:50 +00:00
{
2016-12-23 06:41:39 +00:00
return v >= EState::CardMount && v <= EState::CardFormat;
2016-12-20 21:51:50 +00:00
}
2016-12-29 05:53:00 +00:00
static bool IsCardWriting(EState v)
2016-12-20 21:51:50 +00:00
{
2016-12-24 05:23:50 +00:00
if (v < EState::CardProbe)
2016-12-20 21:51:50 +00:00
return false;
2016-12-24 05:23:50 +00:00
if (v == EState::CardCheck)
2016-12-20 21:51:50 +00:00
return false;
2016-12-24 05:23:50 +00:00
if (v == EState::FileRead)
2016-12-20 21:51:50 +00:00
return false;
return true;
}
};
}
}
#endif // __URDE_CMEMORYCARDDRIVER_HPP__