GCMemcard: Use std::array for DEntry.m_gamecode.

This commit is contained in:
Admiral H. Curtiss 2018-11-18 23:49:25 +01:00
parent 0c638ad858
commit deadec608e
3 changed files with 34 additions and 25 deletions

View File

@ -328,7 +328,7 @@ u8 GCMemcard::GetNumFiles() const
u8 j = 0; u8 j = 0;
for (int i = 0; i < DIRLEN; i++) for (int i = 0; i < DIRLEN; i++)
{ {
if (BE32(CurrentDir->m_dir_entries[i].m_gamecode) != 0xFFFFFFFF) if (CurrentDir->m_dir_entries[i].m_gamecode != DEntry::UNINITIALIZED_GAMECODE)
j++; j++;
} }
return j; return j;
@ -341,7 +341,7 @@ u8 GCMemcard::GetFileIndex(u8 fileNumber) const
u8 j = 0; u8 j = 0;
for (u8 i = 0; i < DIRLEN; i++) for (u8 i = 0; i < DIRLEN; i++)
{ {
if (BE32(CurrentDir->m_dir_entries[i].m_gamecode) != 0xFFFFFFFF) if (CurrentDir->m_dir_entries[i].m_gamecode != DEntry::UNINITIALIZED_GAMECODE)
{ {
if (j == fileNumber) if (j == fileNumber)
{ {
@ -370,7 +370,7 @@ u8 GCMemcard::TitlePresent(const DEntry& d) const
u8 i = 0; u8 i = 0;
while (i < DIRLEN) while (i < DIRLEN)
{ {
if ((BE32(CurrentDir->m_dir_entries[i].m_gamecode) == BE32(d.m_gamecode)) && if (CurrentDir->m_dir_entries[i].m_gamecode == d.m_gamecode &&
CurrentDir->m_dir_entries[i].m_filename == d.m_filename) CurrentDir->m_dir_entries[i].m_filename == d.m_filename)
{ {
break; break;
@ -382,7 +382,8 @@ u8 GCMemcard::TitlePresent(const DEntry& d) const
bool GCMemcard::GCI_FileName(u8 index, std::string& filename) const bool GCMemcard::GCI_FileName(u8 index, std::string& filename) const
{ {
if (!m_valid || index >= DIRLEN || (BE32(CurrentDir->m_dir_entries[index].m_gamecode) == 0xFFFFFFFF)) if (!m_valid || index >= DIRLEN ||
CurrentDir->m_dir_entries[index].m_gamecode == DEntry::UNINITIALIZED_GAMECODE)
return false; return false;
filename = CurrentDir->m_dir_entries[index].GCI_FileName(); filename = CurrentDir->m_dir_entries[index].GCI_FileName();
@ -397,7 +398,9 @@ std::string GCMemcard::DEntry_GameCode(u8 index) const
if (!m_valid || index >= DIRLEN) if (!m_valid || index >= DIRLEN)
return ""; return "";
return std::string((const char*)CurrentDir->m_dir_entries[index].m_gamecode, 4); return std::string(
reinterpret_cast<const char*>(CurrentDir->m_dir_entries[index].m_gamecode.data()),
CurrentDir->m_dir_entries[index].m_gamecode.size());
} }
std::string GCMemcard::DEntry_Makercode(u8 index) const std::string GCMemcard::DEntry_Makercode(u8 index) const
@ -681,7 +684,7 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
// find first free dir entry // find first free dir entry
for (int i = 0; i < DIRLEN; i++) for (int i = 0; i < DIRLEN; i++)
{ {
if (BE32(UpdatedDir.m_dir_entries[i].m_gamecode) == 0xFFFFFFFF) if (UpdatedDir.m_dir_entries[i].m_gamecode == DEntry::UNINITIALIZED_GAMECODE)
{ {
UpdatedDir.m_dir_entries[i] = direntry; UpdatedDir.m_dir_entries[i] = direntry;
UpdatedDir.m_dir_entries[i].m_first_block = firstBlock; UpdatedDir.m_dir_entries[i].m_first_block = firstBlock;

View File

@ -167,15 +167,18 @@ struct DEntry
DEntry() { memset(this, 0xFF, DENTRY_SIZE); } DEntry() { memset(this, 0xFF, DENTRY_SIZE); }
std::string GCI_FileName() const std::string GCI_FileName() const
{ {
std::string filename = std::string((char*)m_makercode, 2) + '-' + std::string filename =
std::string((char*)m_gamecode, 4) + '-' + std::string((char*)m_makercode, 2) + '-' +
reinterpret_cast<const char*>(m_filename.data()) + ".gci"; std::string(reinterpret_cast<const char*>(m_gamecode.data()), m_gamecode.size()) + '-' +
reinterpret_cast<const char*>(m_filename.data()) + ".gci";
return Common::EscapeFileName(filename); return Common::EscapeFileName(filename);
} }
u8 m_gamecode[4]; // 0x00 0x04 Gamecode static constexpr std::array<u8, 4> UNINITIALIZED_GAMECODE = {0xFF, 0xFF, 0xFF, 0xFF};
u8 m_makercode[2]; // 0x04 0x02 Makercode
u8 m_unused_1; // 0x06 0x01 reserved/unused (always 0xff, has no effect) std::array<u8, 4> m_gamecode; // 0x00 0x04 Gamecode
u8 m_makercode[2]; // 0x04 0x02 Makercode
u8 m_unused_1; // 0x06 0x01 reserved/unused (always 0xff, has no effect)
u8 m_banner_and_icon_flags; // 0x07 0x01 banner gfx format and icon animation (Image Key) u8 m_banner_and_icon_flags; // 0x07 0x01 banner gfx format and icon animation (Image Key)
// Bit(s) Description // Bit(s) Description
// 2 Icon Animation 0: forward 1: ping-pong // 2 Icon Animation 0: forward 1: ping-pong

View File

@ -79,7 +79,7 @@ int GCMemcardDirectory::LoadGCI(const std::string& file_name, bool current_game_
return NO_INDEX; return NO_INDEX;
} }
if (m_game_id == BE32(gci.m_gci_header.m_gamecode)) if (m_game_id == BE32(gci.m_gci_header.m_gamecode.data()))
{ {
gci.LoadSaveBlocks(); gci.LoadSaveBlocks();
} }
@ -166,7 +166,7 @@ std::vector<std::string> GCMemcardDirectory::GetFileNamesForGameID(const std::st
// card (see above method), but since we're only loading the saves for one GameID here, we're // card (see above method), but since we're only loading the saves for one GameID here, we're
// definitely not going to run out of space. // definitely not going to run out of space.
if (game_code == BE32(gci.m_gci_header.m_gamecode)) if (game_code == BE32(gci.m_gci_header.m_gamecode.data()))
{ {
loaded_saves.push_back(gci_filename); loaded_saves.push_back(gci_filename);
filenames.push_back(file_name); filenames.push_back(file_name);
@ -436,9 +436,10 @@ inline void GCMemcardDirectory::SyncSaves()
for (u32 i = 0; i < DIRLEN; ++i) for (u32 i = 0; i < DIRLEN; ++i)
{ {
if (BE32(current->m_dir_entries[i].m_gamecode) != 0xFFFFFFFF) if (current->m_dir_entries[i].m_gamecode != DEntry::UNINITIALIZED_GAMECODE)
{ {
INFO_LOG(EXPANSIONINTERFACE, "Syncing save 0x%x", *(u32*)&(current->m_dir_entries[i].m_gamecode)); INFO_LOG(EXPANSIONINTERFACE, "Syncing save 0x%x",
BE32(current->m_dir_entries[i].m_gamecode.data()));
bool added = false; bool added = false;
while (i >= m_saves.size()) while (i >= m_saves.size())
{ {
@ -447,18 +448,20 @@ inline void GCMemcardDirectory::SyncSaves()
added = true; added = true;
} }
if (added || memcmp((u8*)&(m_saves[i].m_gci_header), (u8*)&(current->m_dir_entries[i]), DENTRY_SIZE)) if (added ||
memcmp((u8*)&(m_saves[i].m_gci_header), (u8*)&(current->m_dir_entries[i]), DENTRY_SIZE))
{ {
m_saves[i].m_dirty = true; m_saves[i].m_dirty = true;
u32 gamecode = BE32(m_saves[i].m_gci_header.m_gamecode); u32 gamecode = BE32(m_saves[i].m_gci_header.m_gamecode.data());
u32 new_gamecode = BE32(current->m_dir_entries[i].m_gamecode); u32 new_gamecode = BE32(current->m_dir_entries[i].m_gamecode.data());
u32 old_start = m_saves[i].m_gci_header.m_first_block; u32 old_start = m_saves[i].m_gci_header.m_first_block;
u32 new_start = current->m_dir_entries[i].m_first_block; u32 new_start = current->m_dir_entries[i].m_first_block;
if ((gamecode != 0xFFFFFFFF) && (gamecode != new_gamecode)) if ((gamecode != 0xFFFFFFFF) && (gamecode != new_gamecode))
{ {
PanicAlertT("Game overwrote with another games save. Data corruption ahead 0x%x, 0x%x", PanicAlertT("Game overwrote with another games save. Data corruption ahead 0x%x, 0x%x",
BE32(m_saves[i].m_gci_header.m_gamecode), BE32(current->m_dir_entries[i].m_gamecode)); BE32(m_saves[i].m_gci_header.m_gamecode.data()),
BE32(current->m_dir_entries[i].m_gamecode.data()));
} }
memcpy((u8*)&(m_saves[i].m_gci_header), (u8*)&(current->m_dir_entries[i]), DENTRY_SIZE); memcpy((u8*)&(m_saves[i].m_gci_header), (u8*)&(current->m_dir_entries[i]), DENTRY_SIZE);
if (old_start != new_start) if (old_start != new_start)
@ -476,8 +479,8 @@ inline void GCMemcardDirectory::SyncSaves()
else if ((i < m_saves.size()) && (*(u32*)&(m_saves[i].m_gci_header) != 0xFFFFFFFF)) else if ((i < m_saves.size()) && (*(u32*)&(m_saves[i].m_gci_header) != 0xFFFFFFFF))
{ {
INFO_LOG(EXPANSIONINTERFACE, "Clearing and/or deleting save 0x%x", INFO_LOG(EXPANSIONINTERFACE, "Clearing and/or deleting save 0x%x",
BE32(m_saves[i].m_gci_header.m_gamecode)); BE32(m_saves[i].m_gci_header.m_gamecode.data()));
*(u32*)&(m_saves[i].m_gci_header.m_gamecode) = 0xFFFFFFFF; m_saves[i].m_gci_header.m_gamecode = DEntry::UNINITIALIZED_GAMECODE;
m_saves[i].m_save_data.clear(); m_saves[i].m_save_data.clear();
m_saves[i].m_used_blocks.clear(); m_saves[i].m_used_blocks.clear();
m_saves[i].m_dirty = true; m_saves[i].m_dirty = true;
@ -488,7 +491,7 @@ inline s32 GCMemcardDirectory::SaveAreaRW(u32 block, bool writing)
{ {
for (u16 i = 0; i < m_saves.size(); ++i) for (u16 i = 0; i < m_saves.size(); ++i)
{ {
if (BE32(m_saves[i].m_gci_header.m_gamecode) != 0xFFFFFFFF) if (m_saves[i].m_gci_header.m_gamecode != DEntry::UNINITIALIZED_GAMECODE)
{ {
if (m_saves[i].m_used_blocks.size() == 0) if (m_saves[i].m_used_blocks.size() == 0)
{ {
@ -585,7 +588,7 @@ void GCMemcardDirectory::FlushToFile()
{ {
if (m_saves[i].m_dirty) if (m_saves[i].m_dirty)
{ {
if (BE32(m_saves[i].m_gci_header.m_gamecode) != 0xFFFFFFFF) if (m_saves[i].m_gci_header.m_gamecode != DEntry::UNINITIALIZED_GAMECODE)
{ {
m_saves[i].m_dirty = false; m_saves[i].m_dirty = false;
if (m_saves[i].m_save_data.size() == 0) if (m_saves[i].m_save_data.size() == 0)
@ -654,7 +657,7 @@ void GCMemcardDirectory::FlushToFile()
// simultaneously // simultaneously
// this ensures that the save data for all of the current games gci files are stored in the // this ensures that the save data for all of the current games gci files are stored in the
// savestate // savestate
u32 gamecode = BE32(m_saves[i].m_gci_header.m_gamecode); u32 gamecode = BE32(m_saves[i].m_gci_header.m_gamecode.data());
if (gamecode != m_game_id && gamecode != 0xFFFFFFFF && m_saves[i].m_save_data.size()) if (gamecode != m_game_id && gamecode != 0xFFFFFFFF && m_saves[i].m_save_data.size())
{ {
INFO_LOG(EXPANSIONINTERFACE, "Flushing savedata to disk for %s", INFO_LOG(EXPANSIONINTERFACE, "Flushing savedata to disk for %s",