From 0052b313d6a5f4749043ce89531035a94e3c813c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 4 May 2019 23:28:52 +0200 Subject: [PATCH] GCMemcard: Directory: Move code out of header, add some boundary checks, fix naming conventions. --- Source/Core/Core/HW/GCMemcard/GCMemcard.cpp | 23 +++++++++++ Source/Core/Core/HW/GCMemcard/GCMemcard.h | 40 +++++++++++-------- .../Core/HW/GCMemcard/GCMemcardDirectory.cpp | 2 +- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp index 9eec76d717..62063f2cc9 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp @@ -1387,3 +1387,26 @@ s32 GCMemcard::PSO_MakeSaveGameValid(const Header& cardheader, const DEntry& dir return 1; } + +Directory::Directory() +{ + memset(this, 0xFF, BLOCK_SIZE); + m_update_counter = 0; + m_checksum = BE16(0xF003); + m_checksum_inv = 0; +} + +bool Directory::Replace(const DEntry& entry, size_t index) +{ + if (index >= m_dir_entries.size()) + return false; + + m_dir_entries[index] = entry; + FixChecksums(); + return true; +} + +void Directory::FixChecksums() +{ + calc_checksumsBE((u16*)this, 0xFFE, &m_checksum, &m_checksum_inv); +} diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h index 662257715d..6bf6bf48ee 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h @@ -272,24 +272,30 @@ static_assert(sizeof(DEntry) == DENTRY_SIZE); struct Directory { - std::array m_dir_entries; // 0x0000 Directory Entries (max 127) + // 127 files of 0x40 bytes each + std::array m_dir_entries; + + // 0x3a bytes at 0x1fc0: Unused, always 0xFF std::array m_padding; - Common::BigEndianValue m_update_counter; // 0x1ffa 2 Update Counter - u16 m_checksum; // 0x1ffc 2 Additive Checksum - u16 m_checksum_inv; // 0x1ffe 2 Inverse Checksum - Directory() - { - memset(this, 0xFF, BLOCK_SIZE); - m_update_counter = 0; - m_checksum = BE16(0xF003); - m_checksum_inv = 0; - } - void Replace(DEntry d, int idx) - { - m_dir_entries[idx] = d; - fixChecksums(); - } - void fixChecksums() { calc_checksumsBE((u16*)this, 0xFFE, &m_checksum, &m_checksum_inv); } + + // 2 bytes at 0x1ffa: Update Counter + // TODO: What happens if this overflows? Is there a special case for preferring 0 over max value? + Common::BigEndianValue m_update_counter; + + // 2 bytes at 0x1ffc: Additive Checksum + u16 m_checksum; + + // 2 bytes at 0x1ffe: Inverse Checksum + u16 m_checksum_inv; + + // Constructs an empty Directory block. + Directory(); + + // Replaces the file metadata at the given index (range 0-126) + // with the given DEntry data. + bool Replace(const DEntry& entry, size_t index); + + void FixChecksums(); }; static_assert(sizeof(Directory) == BLOCK_SIZE); diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp index 7b5e56678f..0353e9e4b8 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp @@ -215,7 +215,7 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u } m_loaded_saves.clear(); - m_dir1.fixChecksums(); + m_dir1.FixChecksums(); m_dir2 = m_dir1; m_bat2 = m_bat1;