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;
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++;
}
return j;
@ -341,7 +341,7 @@ u8 GCMemcard::GetFileIndex(u8 fileNumber) const
u8 j = 0;
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)
{
@ -370,7 +370,7 @@ u8 GCMemcard::TitlePresent(const DEntry& d) const
u8 i = 0;
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)
{
break;
@ -382,7 +382,8 @@ u8 GCMemcard::TitlePresent(const DEntry& d) 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;
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)
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
@ -681,7 +684,7 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
// find first free dir entry
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].m_first_block = firstBlock;

View File

@ -167,15 +167,18 @@ struct DEntry
DEntry() { memset(this, 0xFF, DENTRY_SIZE); }
std::string GCI_FileName() const
{
std::string filename = std::string((char*)m_makercode, 2) + '-' +
std::string((char*)m_gamecode, 4) + '-' +
reinterpret_cast<const char*>(m_filename.data()) + ".gci";
std::string filename =
std::string((char*)m_makercode, 2) + '-' +
std::string(reinterpret_cast<const char*>(m_gamecode.data()), m_gamecode.size()) + '-' +
reinterpret_cast<const char*>(m_filename.data()) + ".gci";
return Common::EscapeFileName(filename);
}
u8 m_gamecode[4]; // 0x00 0x04 Gamecode
u8 m_makercode[2]; // 0x04 0x02 Makercode
u8 m_unused_1; // 0x06 0x01 reserved/unused (always 0xff, has no effect)
static constexpr std::array<u8, 4> UNINITIALIZED_GAMECODE = {0xFF, 0xFF, 0xFF, 0xFF};
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)
// Bit(s) Description
// 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;
}
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();
}
@ -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
// 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);
filenames.push_back(file_name);
@ -436,9 +436,10 @@ inline void GCMemcardDirectory::SyncSaves()
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;
while (i >= m_saves.size())
{
@ -447,18 +448,20 @@ inline void GCMemcardDirectory::SyncSaves()
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;
u32 gamecode = BE32(m_saves[i].m_gci_header.m_gamecode);
u32 new_gamecode = BE32(current->m_dir_entries[i].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.data());
u32 old_start = m_saves[i].m_gci_header.m_first_block;
u32 new_start = current->m_dir_entries[i].m_first_block;
if ((gamecode != 0xFFFFFFFF) && (gamecode != new_gamecode))
{
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);
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))
{
INFO_LOG(EXPANSIONINTERFACE, "Clearing and/or deleting save 0x%x",
BE32(m_saves[i].m_gci_header.m_gamecode));
*(u32*)&(m_saves[i].m_gci_header.m_gamecode) = 0xFFFFFFFF;
BE32(m_saves[i].m_gci_header.m_gamecode.data()));
m_saves[i].m_gci_header.m_gamecode = DEntry::UNINITIALIZED_GAMECODE;
m_saves[i].m_save_data.clear();
m_saves[i].m_used_blocks.clear();
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)
{
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)
{
@ -585,7 +588,7 @@ void GCMemcardDirectory::FlushToFile()
{
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;
if (m_saves[i].m_save_data.size() == 0)
@ -654,7 +657,7 @@ void GCMemcardDirectory::FlushToFile()
// simultaneously
// this ensures that the save data for all of the current games gci files are stored in the
// 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())
{
INFO_LOG(EXPANSIONINTERFACE, "Flushing savedata to disk for %s",