CMemoryCardDriver: Make use of std::array where applicable

Stronger typing and also allows eliminating several hardcoded data
sizes.
This commit is contained in:
Lioncash 2020-04-06 06:15:50 -04:00
parent c97fedd989
commit 296cb3df2b
2 changed files with 43 additions and 30 deletions

View File

@ -1,11 +1,13 @@
#include "Runtime/MP1/CMemoryCardDriver.hpp" #include "Runtime/MP1/CMemoryCardDriver.hpp"
#include <array>
#include "Runtime/CCRC32.hpp" #include "Runtime/CCRC32.hpp"
#include "Runtime/MP1/MP1.hpp" #include "Runtime/MP1/MP1.hpp"
namespace urde::MP1 { namespace urde::MP1 {
static const char* SaveFileNames[] = {"MetroidPrime A", "MetroidPrime B"}; constexpr std::array SaveFileNames{"MetroidPrime A", "MetroidPrime B"};
using ECardResult = kabufuda::ECardResult; using ECardResult = kabufuda::ECardResult;
using ECardSlot = kabufuda::ECardSlot; using ECardSlot = kabufuda::ECardSlot;
@ -100,19 +102,19 @@ ECardResult CMemoryCardDriver::SFileInfo::GetSaveDataOffset(u32& offOut) const {
CMemoryCardDriver::SGameFileSlot::SGameFileSlot() { InitializeFromGameState(); } CMemoryCardDriver::SGameFileSlot::SGameFileSlot() { InitializeFromGameState(); }
CMemoryCardDriver::SGameFileSlot::SGameFileSlot(CMemoryInStream& in) { CMemoryCardDriver::SGameFileSlot::SGameFileSlot(CMemoryInStream& in) {
in.readBytesToBuf(x0_saveBuffer, 940); in.readBytesToBuf(x0_saveBuffer.data(), x0_saveBuffer.size());
x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer); x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer.data());
} }
void CMemoryCardDriver::SGameFileSlot::InitializeFromGameState() { void CMemoryCardDriver::SGameFileSlot::InitializeFromGameState() {
CBitStreamWriter w(x0_saveBuffer, 940); CBitStreamWriter w(x0_saveBuffer.data(), x0_saveBuffer.size());
g_GameState->PutTo(w); g_GameState->PutTo(w);
w.Flush(); w.Flush();
x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer); x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer.data());
} }
void CMemoryCardDriver::SGameFileSlot::LoadGameState(u32 idx) { void CMemoryCardDriver::SGameFileSlot::LoadGameState(u32 idx) {
CBitStreamReader r(x0_saveBuffer, 940); CBitStreamReader r(x0_saveBuffer.data(), x0_saveBuffer.size());
static_cast<MP1::CMain*>(g_Main)->StreamNewGameState(r, idx); static_cast<MP1::CMain*>(g_Main)->StreamNewGameState(r, idx);
} }
@ -146,8 +148,9 @@ const CGameState::GameFileStateInfo* CMemoryCardDriver::GetGameFileStateInfo(int
CMemoryCardDriver::SSaveHeader CMemoryCardDriver::LoadSaveHeader(CMemoryInStream& in) { CMemoryCardDriver::SSaveHeader CMemoryCardDriver::LoadSaveHeader(CMemoryInStream& in) {
SSaveHeader ret; SSaveHeader ret;
ret.x0_version = in.readUint32Big(); ret.x0_version = in.readUint32Big();
for (int i = 0; i < 3; ++i) for (bool& present : ret.x4_savePresent) {
ret.x4_savePresent[i] = in.readBool(); present = in.readBool();
}
return ret; return ret;
} }
@ -167,27 +170,30 @@ void CMemoryCardDriver::ReadFinished() {
x20_fileTime = stat.GetTime(); x20_fileTime = stat.GetTime();
CMemoryInStream r(fileInfo.x34_saveData.data(), 3004); CMemoryInStream r(fileInfo.x34_saveData.data(), 3004);
SSaveHeader header = LoadSaveHeader(r); SSaveHeader header = LoadSaveHeader(r);
r.readBytesToBuf(x30_systemData, 174); r.readBytesToBuf(x30_systemData.data(), x30_systemData.size());
for (int i = 0; i < 3; ++i) for (size_t i = 0; i < xe4_fileSlots.size(); ++i) {
if (header.x4_savePresent[i]) if (header.x4_savePresent[i]) {
xe4_fileSlots[i] = LoadSaveFile(r); xe4_fileSlots[i] = LoadSaveFile(r);
}
}
if (x19d_importPersistent) if (x19d_importPersistent) {
ImportPersistentOptions(); ImportPersistentOptions();
}
} }
void CMemoryCardDriver::ImportPersistentOptions() { void CMemoryCardDriver::ImportPersistentOptions() {
CBitStreamReader r(x30_systemData, 174); CBitStreamReader r(x30_systemData.data(), x30_systemData.size());
CPersistentOptions opts(r); CPersistentOptions opts(r);
g_GameState->ImportPersistentOptions(opts); g_GameState->ImportPersistentOptions(opts);
} }
void CMemoryCardDriver::ExportPersistentOptions() { void CMemoryCardDriver::ExportPersistentOptions() {
CBitStreamReader r(x30_systemData, 174); CBitStreamReader r(x30_systemData.data(), x30_systemData.size());
CPersistentOptions opts(r); CPersistentOptions opts(r);
g_GameState->ExportPersistentOptions(opts); g_GameState->ExportPersistentOptions(opts);
CBitStreamWriter w(x30_systemData, 174); CBitStreamWriter w(x30_systemData.data(), x30_systemData.size());
opts.PutTo(w); opts.PutTo(w);
} }
@ -635,7 +641,7 @@ void CMemoryCardDriver::BuildNewFileSlot(u32 saveIdx) {
slot = std::make_unique<SGameFileSlot>(); slot = std::make_unique<SGameFileSlot>();
slot->LoadGameState(saveIdx); slot->LoadGameState(saveIdx);
CBitStreamReader r(x30_systemData, 174); CBitStreamReader r(x30_systemData.data(), x30_systemData.size());
g_GameState->ReadPersistentOptions(r); g_GameState->ReadPersistentOptions(r);
ImportPersistentOptions(); ImportPersistentOptions();
g_GameState->SetCardSerial(x28_cardSerial); g_GameState->SetCardSerial(x28_cardSerial);
@ -653,7 +659,7 @@ void CMemoryCardDriver::BuildExistingFileSlot(u32 saveIdx) {
else else
slot->InitializeFromGameState(); slot->InitializeFromGameState();
CBitStreamWriter w(x30_systemData, 174); CBitStreamWriter w(x30_systemData.data(), x30_systemData.size());
g_GameState->PutTo(w); g_GameState->PutTo(w);
} }
@ -674,15 +680,18 @@ void CMemoryCardDriver::InitializeFileInfo() {
CMemoryOutStream w = x198_fileInfo->BeginMemoryOut(3004); CMemoryOutStream w = x198_fileInfo->BeginMemoryOut(3004);
SSaveHeader header; SSaveHeader header;
for (int i = 0; i < 3; ++i) for (size_t i = 0; i < xe4_fileSlots.size(); ++i) {
header.x4_savePresent[i] = xe4_fileSlots[i].operator bool(); header.x4_savePresent[i] = xe4_fileSlots[i] != nullptr;
}
header.DoPut(w); header.DoPut(w);
w.writeBytes(x30_systemData, 174); w.writeBytes(x30_systemData.data(), x30_systemData.size());
for (int i = 0; i < 3; ++i) for (auto& fileSlot : xe4_fileSlots) {
if (xe4_fileSlots[i]) if (fileSlot) {
xe4_fileSlots[i]->DoPut(w); fileSlot->DoPut(w);
}
}
} }
void CMemoryCardDriver::WriteBackupBuf() { void CMemoryCardDriver::WriteBackupBuf() {

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -87,22 +88,25 @@ private:
struct SSaveHeader { struct SSaveHeader {
u32 x0_version = 0; u32 x0_version = 0;
bool x4_savePresent[3]; std::array<bool, 3> x4_savePresent{};
void DoPut(CMemoryOutStream& out) const { void DoPut(CMemoryOutStream& out) const {
out.writeUint32Big(x0_version); out.writeUint32Big(x0_version);
for (int i = 0; i < 3; ++i) for (const bool savePresent : x4_savePresent) {
out.writeBool(x4_savePresent[i]); out.writeBool(savePresent);
}
} }
}; };
struct SGameFileSlot { struct SGameFileSlot {
u8 x0_saveBuffer[940] = {}; std::array<u8, 940> x0_saveBuffer{};
CGameState::GameFileStateInfo x944_fileInfo; CGameState::GameFileStateInfo x944_fileInfo;
SGameFileSlot(); SGameFileSlot();
explicit SGameFileSlot(CMemoryInStream& in); explicit SGameFileSlot(CMemoryInStream& in);
void InitializeFromGameState(); void InitializeFromGameState();
void LoadGameState(u32 idx); void LoadGameState(u32 idx);
void DoPut(CMemoryOutStream& w) const { w.writeBytes(x0_saveBuffer, 940); } void DoPut(CMemoryOutStream& w) const { w.writeBytes(x0_saveBuffer.data(), x0_saveBuffer.size()); }
}; };
enum class EFileState { Unknown, NoFile, File, BadFile }; enum class EFileState { Unknown, NoFile, File, BadFile };
@ -117,8 +121,8 @@ private:
s32 x1c_cardFreeFiles = 0; s32 x1c_cardFreeFiles = 0;
u32 x20_fileTime = 0; u32 x20_fileTime = 0;
u64 x28_cardSerial = 0; u64 x28_cardSerial = 0;
u8 x30_systemData[174] = {}; std::array<u8, 174> x30_systemData{};
std::unique_ptr<SGameFileSlot> xe4_fileSlots[3]; std::array<std::unique_ptr<SGameFileSlot>, 3> xe4_fileSlots;
std::vector<std::pair<EFileState, SFileInfo>> x100_mcFileInfos; std::vector<std::pair<EFileState, SFileInfo>> x100_mcFileInfos;
u32 x194_fileIdx = -1; u32 x194_fileIdx = -1;
std::unique_ptr<CMemoryCardSys::CCardFileInfo> x198_fileInfo; std::unique_ptr<CMemoryCardSys::CCardFileInfo> x198_fileInfo;