GCMemcard: As far as I can tell, the directory and BAT blocks aren't really main and backup, but just two blocks that store data are written to alternately. So store them as an std::array of 2 blocks instead of an explicit 'backup' block.
This commit is contained in:
parent
0aaf24b9cc
commit
7ff65db3b2
|
@ -99,25 +99,25 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mcdFile.ReadBytes(&m_directory_block, BLOCK_SIZE))
|
||||
if (!mcdFile.ReadBytes(&m_directory_blocks[0], BLOCK_SIZE))
|
||||
{
|
||||
PanicAlertT("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mcdFile.ReadBytes(&m_directory_backup_block, BLOCK_SIZE))
|
||||
if (!mcdFile.ReadBytes(&m_directory_blocks[1], BLOCK_SIZE))
|
||||
{
|
||||
PanicAlertT("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mcdFile.ReadBytes(&m_bat_block, BLOCK_SIZE))
|
||||
if (!mcdFile.ReadBytes(&m_bat_blocks[0], BLOCK_SIZE))
|
||||
{
|
||||
PanicAlertT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mcdFile.ReadBytes(&m_bat_backup_block, BLOCK_SIZE))
|
||||
if (!mcdFile.ReadBytes(&m_bat_blocks[1], BLOCK_SIZE))
|
||||
{
|
||||
PanicAlertT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
||||
return;
|
||||
|
@ -144,8 +144,8 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
|||
else
|
||||
{
|
||||
// backup is correct, restore
|
||||
m_directory_block = m_directory_backup_block;
|
||||
m_bat_block = m_bat_backup_block;
|
||||
m_directory_blocks[0] = m_directory_blocks[1];
|
||||
m_bat_blocks[0] = m_bat_blocks[1];
|
||||
|
||||
// update checksums
|
||||
csums = TestChecksums();
|
||||
|
@ -163,8 +163,8 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
|||
else
|
||||
{
|
||||
// backup is correct, restore
|
||||
m_directory_block = m_directory_backup_block;
|
||||
m_bat_block = m_bat_backup_block;
|
||||
m_directory_blocks[0] = m_directory_blocks[1];
|
||||
m_bat_blocks[0] = m_bat_blocks[1];
|
||||
|
||||
// update checksums
|
||||
csums = TestChecksums();
|
||||
|
@ -209,25 +209,25 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
|||
|
||||
void GCMemcard::InitDirBatPointers()
|
||||
{
|
||||
if (m_directory_block.m_update_counter > m_directory_backup_block.m_update_counter)
|
||||
if (m_directory_blocks[0].m_update_counter > m_directory_blocks[1].m_update_counter)
|
||||
{
|
||||
m_current_directory_block = &m_directory_block;
|
||||
m_previous_directory_block = &m_directory_backup_block;
|
||||
m_current_directory_block = &m_directory_blocks[0];
|
||||
m_previous_directory_block = &m_directory_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_directory_block = &m_directory_backup_block;
|
||||
m_previous_directory_block = &m_directory_block;
|
||||
m_current_directory_block = &m_directory_blocks[1];
|
||||
m_previous_directory_block = &m_directory_blocks[0];
|
||||
}
|
||||
if (m_bat_block.m_update_counter > m_bat_backup_block.m_update_counter)
|
||||
if (m_bat_blocks[0].m_update_counter > m_bat_blocks[1].m_update_counter)
|
||||
{
|
||||
m_current_bat_block = &m_bat_block;
|
||||
m_previous_bat_block = &m_bat_backup_block;
|
||||
m_current_bat_block = &m_bat_blocks[0];
|
||||
m_previous_bat_block = &m_bat_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_bat_block = &m_bat_backup_block;
|
||||
m_previous_bat_block = &m_bat_block;
|
||||
m_current_bat_block = &m_bat_blocks[1];
|
||||
m_previous_bat_block = &m_bat_blocks[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,10 +242,10 @@ bool GCMemcard::Save()
|
|||
mcdFile.Seek(0, SEEK_SET);
|
||||
|
||||
mcdFile.WriteBytes(&m_header_block, BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_directory_block, BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_directory_backup_block, BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_bat_block, BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_bat_backup_block, BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_directory_blocks[0], BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_directory_blocks[1], BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_bat_blocks[0], BLOCK_SIZE);
|
||||
mcdFile.WriteBytes(&m_bat_blocks[1], BLOCK_SIZE);
|
||||
for (unsigned int i = 0; i < m_size_blocks - MC_FST_BLOCKS; ++i)
|
||||
{
|
||||
mcdFile.WriteBytes(m_data_blocks[i].block, BLOCK_SIZE);
|
||||
|
@ -286,21 +286,22 @@ u32 GCMemcard::TestChecksums() const
|
|||
if ((m_header_block.m_checksum != csum) || (m_header_block.m_checksum_inv != csum_inv))
|
||||
results |= 1;
|
||||
|
||||
calc_checksumsBE((u16*)&m_directory_block, 0xFFE, &csum, &csum_inv);
|
||||
if ((m_directory_block.m_checksum != csum) || (m_directory_block.m_checksum_inv != csum_inv))
|
||||
calc_checksumsBE((u16*)&m_directory_blocks[0], 0xFFE, &csum, &csum_inv);
|
||||
if ((m_directory_blocks[0].m_checksum != csum) ||
|
||||
(m_directory_blocks[0].m_checksum_inv != csum_inv))
|
||||
results |= 2;
|
||||
|
||||
calc_checksumsBE((u16*)&m_directory_backup_block, 0xFFE, &csum, &csum_inv);
|
||||
if ((m_directory_backup_block.m_checksum != csum) ||
|
||||
(m_directory_backup_block.m_checksum_inv != csum_inv))
|
||||
calc_checksumsBE((u16*)&m_directory_blocks[1], 0xFFE, &csum, &csum_inv);
|
||||
if ((m_directory_blocks[1].m_checksum != csum) ||
|
||||
(m_directory_blocks[1].m_checksum_inv != csum_inv))
|
||||
results |= 4;
|
||||
|
||||
calc_checksumsBE((u16*)(((u8*)&m_bat_block) + 4), 0xFFE, &csum, &csum_inv);
|
||||
if ((m_bat_block.m_checksum != csum) || (m_bat_block.m_checksum_inv != csum_inv))
|
||||
calc_checksumsBE((u16*)(((u8*)&m_bat_blocks[0]) + 4), 0xFFE, &csum, &csum_inv);
|
||||
if ((m_bat_blocks[0].m_checksum != csum) || (m_bat_blocks[0].m_checksum_inv != csum_inv))
|
||||
results |= 8;
|
||||
|
||||
calc_checksumsBE((u16*)(((u8*)&m_bat_backup_block) + 4), 0xFFE, &csum, &csum_inv);
|
||||
if ((m_bat_backup_block.m_checksum != csum) || (m_bat_backup_block.m_checksum_inv != csum_inv))
|
||||
calc_checksumsBE((u16*)(((u8*)&m_bat_blocks[1]) + 4), 0xFFE, &csum, &csum_inv);
|
||||
if ((m_bat_blocks[1].m_checksum != csum) || (m_bat_blocks[1].m_checksum_inv != csum_inv))
|
||||
results |= 16;
|
||||
|
||||
return results;
|
||||
|
@ -313,14 +314,14 @@ bool GCMemcard::FixChecksums()
|
|||
|
||||
calc_checksumsBE((u16*)&m_header_block, 0xFE, &m_header_block.m_checksum,
|
||||
&m_header_block.m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_directory_block, 0xFFE, &m_directory_block.m_checksum,
|
||||
&m_directory_block.m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_directory_backup_block, 0xFFE, &m_directory_backup_block.m_checksum,
|
||||
&m_directory_backup_block.m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_bat_block + 2, 0xFFE, &m_bat_block.m_checksum,
|
||||
&m_bat_block.m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_bat_backup_block + 2, 0xFFE, &m_bat_backup_block.m_checksum,
|
||||
&m_bat_backup_block.m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_directory_blocks[0], 0xFFE, &m_directory_blocks[0].m_checksum,
|
||||
&m_directory_blocks[0].m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_directory_blocks[1], 0xFFE, &m_directory_blocks[1].m_checksum,
|
||||
&m_directory_blocks[1].m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_bat_blocks[0] + 2, 0xFFE, &m_bat_blocks[0].m_checksum,
|
||||
&m_bat_blocks[0].m_checksum_inv);
|
||||
calc_checksumsBE((u16*)&m_bat_blocks[1] + 2, 0xFFE, &m_bat_blocks[1].m_checksum,
|
||||
&m_bat_blocks[1].m_checksum_inv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -701,15 +702,15 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
|
|||
}
|
||||
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
||||
*m_previous_directory_block = UpdatedDir;
|
||||
if (m_previous_directory_block == &m_directory_block)
|
||||
if (m_previous_directory_block == &m_directory_blocks[0])
|
||||
{
|
||||
m_current_directory_block = &m_directory_block;
|
||||
m_previous_directory_block = &m_directory_backup_block;
|
||||
m_current_directory_block = &m_directory_blocks[0];
|
||||
m_previous_directory_block = &m_directory_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_directory_block = &m_directory_backup_block;
|
||||
m_previous_directory_block = &m_directory_block;
|
||||
m_current_directory_block = &m_directory_blocks[1];
|
||||
m_previous_directory_block = &m_directory_blocks[0];
|
||||
}
|
||||
|
||||
int fileBlocks = direntry.m_block_count;
|
||||
|
@ -737,15 +738,15 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
|
|||
UpdatedBat.m_free_blocks = UpdatedBat.m_free_blocks - fileBlocks;
|
||||
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
||||
*m_previous_bat_block = UpdatedBat;
|
||||
if (m_previous_bat_block == &m_bat_block)
|
||||
if (m_previous_bat_block == &m_bat_blocks[0])
|
||||
{
|
||||
m_current_bat_block = &m_bat_block;
|
||||
m_previous_bat_block = &m_bat_backup_block;
|
||||
m_current_bat_block = &m_bat_blocks[0];
|
||||
m_previous_bat_block = &m_bat_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_bat_block = &m_bat_backup_block;
|
||||
m_previous_bat_block = &m_bat_block;
|
||||
m_current_bat_block = &m_bat_blocks[1];
|
||||
m_previous_bat_block = &m_bat_blocks[0];
|
||||
}
|
||||
|
||||
FixChecksums();
|
||||
|
@ -768,15 +769,15 @@ u32 GCMemcard::RemoveFile(u8 index) // index in the directory array
|
|||
return DELETE_FAIL;
|
||||
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
||||
*m_previous_bat_block = UpdatedBat;
|
||||
if (m_previous_bat_block == &m_bat_block)
|
||||
if (m_previous_bat_block == &m_bat_blocks[0])
|
||||
{
|
||||
m_current_bat_block = &m_bat_block;
|
||||
m_previous_bat_block = &m_bat_backup_block;
|
||||
m_current_bat_block = &m_bat_blocks[0];
|
||||
m_previous_bat_block = &m_bat_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_bat_block = &m_bat_backup_block;
|
||||
m_previous_bat_block = &m_bat_block;
|
||||
m_current_bat_block = &m_bat_blocks[1];
|
||||
m_previous_bat_block = &m_bat_blocks[0];
|
||||
}
|
||||
|
||||
Directory UpdatedDir = *m_current_directory_block;
|
||||
|
@ -804,15 +805,15 @@ u32 GCMemcard::RemoveFile(u8 index) // index in the directory array
|
|||
memset(&(UpdatedDir.m_dir_entries[index]), 0xFF, DENTRY_SIZE);
|
||||
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
||||
*m_previous_directory_block = UpdatedDir;
|
||||
if (m_previous_directory_block == &m_directory_block)
|
||||
if (m_previous_directory_block == &m_directory_blocks[0])
|
||||
{
|
||||
m_current_directory_block = &m_directory_block;
|
||||
m_previous_directory_block = &m_directory_backup_block;
|
||||
m_current_directory_block = &m_directory_blocks[0];
|
||||
m_previous_directory_block = &m_directory_blocks[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_directory_block = &m_directory_backup_block;
|
||||
m_previous_directory_block = &m_directory_block;
|
||||
m_current_directory_block = &m_directory_blocks[1];
|
||||
m_previous_directory_block = &m_directory_blocks[0];
|
||||
}
|
||||
|
||||
FixChecksums();
|
||||
|
@ -1289,14 +1290,14 @@ bool GCMemcard::Format(u8* card_data, bool shift_jis, u16 SizeMb)
|
|||
bool GCMemcard::Format(bool shift_jis, u16 SizeMb)
|
||||
{
|
||||
memset(&m_header_block, 0xFF, BLOCK_SIZE);
|
||||
memset(&m_directory_block, 0xFF, BLOCK_SIZE);
|
||||
memset(&m_directory_backup_block, 0xFF, BLOCK_SIZE);
|
||||
memset(&m_bat_block, 0, BLOCK_SIZE);
|
||||
memset(&m_bat_backup_block, 0, BLOCK_SIZE);
|
||||
memset(&m_directory_blocks[0], 0xFF, BLOCK_SIZE);
|
||||
memset(&m_directory_blocks[1], 0xFF, BLOCK_SIZE);
|
||||
memset(&m_bat_blocks[0], 0, BLOCK_SIZE);
|
||||
memset(&m_bat_blocks[1], 0, BLOCK_SIZE);
|
||||
|
||||
m_header_block = Header(SLOT_A, SizeMb, shift_jis);
|
||||
m_directory_block = m_directory_backup_block = Directory();
|
||||
m_bat_block = m_bat_backup_block = BlockAlloc(SizeMb);
|
||||
m_directory_blocks[0] = m_directory_blocks[1] = Directory();
|
||||
m_bat_blocks[0] = m_bat_blocks[1] = BlockAlloc(SizeMb);
|
||||
|
||||
m_size_mb = SizeMb;
|
||||
m_size_blocks = (u32)m_size_mb * MBIT_TO_BLOCKS;
|
||||
|
|
|
@ -330,10 +330,8 @@ private:
|
|||
u16 m_size_mb;
|
||||
|
||||
Header m_header_block;
|
||||
Directory m_directory_block;
|
||||
Directory m_directory_backup_block;
|
||||
BlockAlloc m_bat_block;
|
||||
BlockAlloc m_bat_backup_block;
|
||||
std::array<Directory, 2> m_directory_blocks;
|
||||
std::array<BlockAlloc, 2> m_bat_blocks;
|
||||
std::vector<GCMBlock> m_data_blocks;
|
||||
|
||||
Directory* m_current_directory_block;
|
||||
|
|
Loading…
Reference in New Issue