metaforce/Runtime/CMemoryCardSys.hpp

183 lines
7.4 KiB
C++
Raw Normal View History

2018-10-07 03:42:33 +00:00
#pragma once
2015-08-17 05:26:58 +00:00
#include <memory>
#include <optional>
#include <string>
2016-09-25 01:58:20 +00:00
#include <vector>
#include "Runtime/CGameHintInfo.hpp"
#include "Runtime/CWorldSaveGameInfo.hpp"
#include "Runtime/CToken.hpp"
#include "Runtime/rstl.hpp"
#include "Runtime/GuiSys/CStringTable.hpp"
#include "Runtime/World/CWorld.hpp"
#include <kabufuda/Card.hpp>
2021-04-10 08:42:06 +00:00
namespace metaforce {
2016-09-25 01:58:20 +00:00
class CDummyWorld;
2016-12-23 06:41:39 +00:00
class CSimplePool;
class CStringTable;
2016-09-25 01:58:20 +00:00
2018-12-08 05:30:43 +00:00
class CSaveWorldMemory {
friend class CMemoryCardSys;
CAssetId x0_strgId;
CAssetId x4_savwId;
u32 x8_areaCount;
std::vector<s32> xc_areaIds;
2018-12-08 05:30:43 +00:00
std::vector<CWorldLayers::Area> x1c_defaultLayerStates;
TLockedToken<CStringTable> x2c_worldName; /* used to be optional */
TLockedToken<CWorldSaveGameInfo> x3c_saveWorld; /* used to be optional */
2016-09-25 01:58:20 +00:00
public:
2018-12-08 05:30:43 +00:00
CAssetId GetWorldNameId() const { return x0_strgId; }
CAssetId GetSaveWorldAssetId() const { return x4_savwId; }
u32 GetAreaCount() const { return x8_areaCount; }
const std::vector<CWorldLayers::Area>& GetDefaultLayerStates() const { return x1c_defaultLayerStates; }
const TLockedToken<CStringTable>& GetWorldName() const { return x2c_worldName; }
const TLockedToken<CWorldSaveGameInfo>& GetSaveWorld() const { return x3c_saveWorld; }
2018-12-08 05:30:43 +00:00
const char16_t* GetFrontEndName() const {
if (!x2c_worldName)
return u"";
return x2c_worldName->GetString(0);
}
2016-09-25 01:58:20 +00:00
};
2018-12-08 05:30:43 +00:00
class CSaveWorldIntermediate {
friend class CMemoryCardSys;
CAssetId x0_mlvlId;
CAssetId x4_strgId;
CAssetId x8_savwId;
std::vector<s32> xc_areaIds;
2018-12-08 05:30:43 +00:00
std::vector<CWorldLayers::Area> x1c_defaultLayerStates;
std::unique_ptr<CDummyWorld> x2c_dummyWorld;
TLockedToken<CWorldSaveGameInfo> x34_saveWorld; /* Used to be auto_ptr */
public:
2018-12-08 05:30:43 +00:00
CSaveWorldIntermediate(CAssetId mlvl, CAssetId savw);
2018-12-08 05:30:43 +00:00
bool InitializePump();
2016-09-25 01:58:20 +00:00
};
2018-12-08 05:30:43 +00:00
class CMemoryCardSys {
TLockedToken<CGameHintInfo> x0_hints;
std::vector<std::pair<CAssetId, CSaveWorldMemory>> xc_memoryWorlds; /* MLVL as key */
std::optional<std::vector<CSaveWorldIntermediate>> x1c_worldInter; /* used to be auto_ptr of vector */
std::vector<std::pair<CAssetId, CWorldSaveGameInfo::EScanCategory>> x20_scanStates;
2018-12-08 05:30:43 +00:00
rstl::reserved_vector<u32, 6> x30_scanCategoryCounts;
2017-01-22 17:36:25 +00:00
2016-09-25 01:58:20 +00:00
public:
static void _ResetCVar(kabufuda::ECardSlot slot);
static void _ResolveDolphinCardPath(const hecl::CVar* cv, kabufuda::ECardSlot slot);
2018-12-08 05:30:43 +00:00
static kabufuda::SystemString ResolveDolphinCardPath(kabufuda::ECardSlot slot);
static bool CreateDolphinCard(kabufuda::ECardSlot slot);
static kabufuda::SystemString _GetDolphinCardPath(kabufuda::ECardSlot slot);
static kabufuda::SystemString _CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin);
2018-12-08 05:30:43 +00:00
using ECardResult = kabufuda::ECardResult;
struct CardResult {
ECardResult result;
CardResult(ECardResult res) : result(res) {}
operator ECardResult() const { return result; }
explicit operator bool() const { return result != ECardResult::READY; }
2018-12-08 05:30:43 +00:00
};
struct CardFileHandle {
kabufuda::ECardSlot slot;
kabufuda::FileHandle handle;
CardFileHandle(kabufuda::ECardSlot slot) : slot(slot) {}
int getFileNo() const { return handle.getFileNo(); }
};
using CardStat = kabufuda::CardStat;
const std::vector<CGameHintInfo::CGameHint>& GetHints() const { return x0_hints->GetHints(); }
const std::vector<std::pair<CAssetId, CSaveWorldMemory>>& GetMemoryWorlds() const { return xc_memoryWorlds; }
const std::vector<std::pair<CAssetId, CWorldSaveGameInfo::EScanCategory>>& GetScanStates() const { return x20_scanStates; }
u32 GetScanCategoryCount(CWorldSaveGameInfo::EScanCategory cat) const { return x30_scanCategoryCounts[int(cat)]; }
2018-12-08 05:30:43 +00:00
std::vector<std::pair<CAssetId, CWorldSaveGameInfo::EScanCategory>>::const_iterator LookupScanState(CAssetId id) const {
2018-12-08 05:30:43 +00:00
return rstl::binary_find(x20_scanStates.cbegin(), x20_scanStates.cend(), id,
[](const std::pair<CAssetId, CWorldSaveGameInfo::EScanCategory>& p) { return p.first; });
2018-12-08 05:30:43 +00:00
}
bool HasSaveWorldMemory(CAssetId wldId) const;
const CSaveWorldMemory& GetSaveWorldMemory(CAssetId wldId) const;
CMemoryCardSys();
bool InitializePump();
struct CCardFileInfo {
struct Icon {
CAssetId x0_id;
kabufuda::EAnimationSpeed x4_speed;
TLockedToken<CTexture> x8_tex;
Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp, const CVParamTransfer& cv);
2016-12-20 21:51:50 +00:00
};
2018-12-08 05:30:43 +00:00
enum class EStatus { Standby, Transferring, Done };
EStatus x0_status = EStatus::Standby;
// CARDFileInfo x4_info;
CardFileHandle m_handle;
std::string x18_fileName;
std::string x28_comment;
CAssetId x3c_bannerTex;
std::optional<TLockedToken<CTexture>> x40_bannerTok;
2018-12-08 05:30:43 +00:00
rstl::reserved_vector<Icon, 8> x50_iconToks;
std::vector<u8> xf4_saveBuffer;
std::vector<u8> x104_cardBuffer;
CVParamTransfer m_texParam = {new TObjOwnerParam<u32>(SBIG('OTEX'))};
CCardFileInfo(kabufuda::ECardSlot port, std::string_view name) : m_handle(port), x18_fileName(name) {}
void LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp);
void LockIconToken(CAssetId iconTxtr, kabufuda::EAnimationSpeed speed, CSimplePool& sp);
kabufuda::ECardSlot GetCardPort() const { return m_handle.slot; }
int GetFileNo() const { return m_handle.getFileNo(); }
u32 CalculateBannerDataSize() const;
u32 CalculateTotalDataSize() const;
void BuildCardBuffer();
void WriteBannerData(CMemoryOutStream& out) const;
void WriteIconData(CMemoryOutStream& out) const;
void SetComment(const std::string& c) { x28_comment = c; }
ECardResult PumpCardTransfer();
ECardResult GetStatus(CardStat& stat) const;
ECardResult CreateFile();
ECardResult WriteFile();
ECardResult CloseFile();
CMemoryOutStream BeginMemoryOut(u32 sz) {
xf4_saveBuffer.resize(sz);
return CMemoryOutStream(xf4_saveBuffer.data(), sz);
2017-07-31 05:19:05 +00:00
}
2018-12-08 05:30:43 +00:00
};
std::pair<CAssetId, TAreaId> GetAreaAndWorldIdForSaveId(s32 saveId) const;
2018-12-08 05:30:43 +00:00
static kabufuda::ProbeResults CardProbe(kabufuda::ECardSlot port);
static ECardResult MountCard(kabufuda::ECardSlot port);
static ECardResult UnmountCard(kabufuda::ECardSlot port);
static ECardResult CheckCard(kabufuda::ECardSlot port);
static ECardResult CreateFile(kabufuda::ECardSlot port, const char* name, u32 size, CardFileHandle& info);
static ECardResult OpenFile(kabufuda::ECardSlot port, const char* name, CardFileHandle& info);
static ECardResult FastOpenFile(kabufuda::ECardSlot port, int fileNo, CardFileHandle& info);
static ECardResult CloseFile(CardFileHandle& info);
static ECardResult ReadFile(CardFileHandle& info, void* buf, s32 length, s32 offset);
static ECardResult WriteFile(CardFileHandle& info, const void* buf, s32 length, s32 offset);
static ECardResult GetNumFreeBytes(kabufuda::ECardSlot port, s32& freeBytes, s32& freeFiles);
static ECardResult GetSerialNo(kabufuda::ECardSlot port, u64& serialOut);
static ECardResult GetResultCode(kabufuda::ECardSlot port);
static ECardResult GetStatus(kabufuda::ECardSlot port, int fileNo, CardStat& statOut);
static ECardResult SetStatus(kabufuda::ECardSlot port, int fileNo, const CardStat& stat);
static ECardResult DeleteFile(kabufuda::ECardSlot port, const char* name);
static ECardResult FastDeleteFile(kabufuda::ECardSlot port, int fileNo);
static ECardResult Rename(kabufuda::ECardSlot port, const char* oldName, const char* newName);
static ECardResult FormatCard(kabufuda::ECardSlot port);
static void CommitToDisk(kabufuda::ECardSlot port);
static void Shutdown();
2015-08-17 05:26:58 +00:00
};
2021-04-10 08:42:06 +00:00
} // namespace metaforce