From 2e1bfe073cc32d2677e1653baaf1f400b79f8c67 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 15 Jun 2020 01:37:17 +0200 Subject: [PATCH 1/2] GCMemcard: Split out MemoryCardBase into its own header, which is the base class for the raw and folder memory cards and has little to do with the actual memory card data structures. --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/Core.vcxproj | 1 + Source/Core/Core/Core.vcxproj.filters | 3 ++ Source/Core/Core/HW/GCMemcard/GCMemcard.h | 22 ------------- Source/Core/Core/HW/GCMemcard/GCMemcardBase.h | 33 +++++++++++++++++++ .../Core/HW/GCMemcard/GCMemcardDirectory.h | 1 + Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h | 1 + 7 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 Source/Core/Core/HW/GCMemcard/GCMemcardBase.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 2b7c141e68..0750be3eba 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -221,6 +221,7 @@ add_library(core HW/GCMemcard/GCIFile.h HW/GCMemcard/GCMemcard.cpp HW/GCMemcard/GCMemcard.h + HW/GCMemcard/GCMemcardBase.h HW/GCMemcard/GCMemcardDirectory.cpp HW/GCMemcard/GCMemcardDirectory.h HW/GCMemcard/GCMemcardRaw.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index deeab45e20..fe33616c2f 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -514,6 +514,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 7fe19d606b..b820c04802 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -1245,6 +1245,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + HW %28Flipper/Hollywood%29\GCMemcard + HW %28Flipper/Hollywood%29\GCMemcard diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h index e650429b81..f772c1214b 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h @@ -158,28 +158,6 @@ constexpr u8 MEMORY_CARD_ICON_FORMAT_CI8_UNIQUE_PALETTE = 3; // each palette entry is 16 bits in RGB5A3 format constexpr u32 MEMORY_CARD_CI8_PALETTE_ENTRIES = 256; -class MemoryCardBase -{ -public: - explicit MemoryCardBase(int card_index = 0, int size_mbits = MBIT_SIZE_MEMORY_CARD_2043) - : m_card_index(card_index), m_nintendo_card_id(size_mbits) - { - } - virtual ~MemoryCardBase() {} - virtual s32 Read(u32 src_address, s32 length, u8* dest_address) = 0; - virtual s32 Write(u32 dest_address, s32 length, const u8* src_address) = 0; - virtual void ClearBlock(u32 address) = 0; - virtual void ClearAll() = 0; - virtual void DoState(PointerWrap& p) = 0; - u32 GetCardId() const { return m_nintendo_card_id; } - bool IsAddressInBounds(u32 address) const { return address <= (m_memory_card_size - 1); } - -protected: - int m_card_index; - u16 m_nintendo_card_id; - u32 m_memory_card_size; -}; - struct GCMBlock { GCMBlock(); diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h new file mode 100644 index 0000000000..6ecbf92c22 --- /dev/null +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h @@ -0,0 +1,33 @@ +// Copyright 2020 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Common/CommonTypes.h" + +#include "Core/HW/GCMemcard/GCMemcard.h" + +class PointerWrap; + +class MemoryCardBase +{ +public: + explicit MemoryCardBase(int card_index = 0, int size_mbits = MBIT_SIZE_MEMORY_CARD_2043) + : m_card_index(card_index), m_nintendo_card_id(size_mbits) + { + } + virtual ~MemoryCardBase() = default; + virtual s32 Read(u32 src_address, s32 length, u8* dest_address) = 0; + virtual s32 Write(u32 dest_address, s32 length, const u8* src_address) = 0; + virtual void ClearBlock(u32 address) = 0; + virtual void ClearAll() = 0; + virtual void DoState(PointerWrap& p) = 0; + u32 GetCardId() const { return m_nintendo_card_id; } + bool IsAddressInBounds(u32 address) const { return address <= (m_memory_card_size - 1); } + +protected: + int m_card_index; + u16 m_nintendo_card_id; + u32 m_memory_card_size; +}; diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h index 2869ba2d32..f3fe9ddaa0 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h @@ -12,6 +12,7 @@ #include "Common/Event.h" #include "Core/HW/GCMemcard/GCIFile.h" #include "Core/HW/GCMemcard/GCMemcard.h" +#include "Core/HW/GCMemcard/GCMemcardBase.h" // Uncomment this to write the system data of the memorycard from directory to disc //#define _WRITE_MC_HEADER 1 diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h index 727d625aa4..f04034f340 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h @@ -11,6 +11,7 @@ #include "Common/Event.h" #include "Common/Flag.h" #include "Core/HW/GCMemcard/GCMemcard.h" +#include "Core/HW/GCMemcard/GCMemcardBase.h" class PointerWrap; From 914ebdf0dd4cfe50ced0788dbf46b5a80eb8a99e Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 15 Jun 2020 02:09:37 +0200 Subject: [PATCH 2/2] GCMemcard: Move from global namespace into a Memcard namespace. --- .../Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp | 12 +- Source/Core/Core/HW/GCMemcard/GCIFile.cpp | 3 + Source/Core/Core/HW/GCMemcard/GCIFile.h | 3 + Source/Core/Core/HW/GCMemcard/GCMemcard.cpp | 3 + Source/Core/Core/HW/GCMemcard/GCMemcard.h | 3 + Source/Core/Core/HW/GCMemcard/GCMemcardBase.h | 2 +- .../Core/HW/GCMemcard/GCMemcardDirectory.cpp | 116 +++++++++--------- .../Core/HW/GCMemcard/GCMemcardDirectory.h | 12 +- .../Core/Core/HW/GCMemcard/GCMemcardRaw.cpp | 8 +- Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h | 2 +- .../DolphinQt/GCMemcardCreateNewDialog.cpp | 2 +- Source/Core/DolphinQt/GCMemcardManager.cpp | 39 +++--- Source/Core/DolphinQt/GCMemcardManager.h | 7 +- .../Core/DolphinQt/Settings/GameCubePane.cpp | 2 +- 14 files changed, 117 insertions(+), 97 deletions(-) diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp index b149b07cf4..b39b6963d7 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp @@ -142,7 +142,7 @@ CEXIMemoryCard::CEXIMemoryCard(const int index, bool gciFolder) : card_index(ind bool useMC251; IniFile gameIni = SConfig::GetInstance().LoadGameIni(); gameIni.GetOrCreateSection("Core")->Get("MemoryCard251", &useMC251, false); - u16 sizeMb = useMC251 ? MBIT_SIZE_MEMORY_CARD_251 : MBIT_SIZE_MEMORY_CARD_2043; + u16 sizeMb = useMC251 ? Memcard::MBIT_SIZE_MEMORY_CARD_251 : Memcard::MBIT_SIZE_MEMORY_CARD_2043; if (gciFolder) { @@ -245,7 +245,7 @@ void CEXIMemoryCard::SetupRawMemcard(u16 sizeMb) SConfig::GetDirectoryForRegion(SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region)); MemoryCard::CheckPath(filename, region_dir, is_slot_a); - if (sizeMb == MBIT_SIZE_MEMORY_CARD_251) + if (sizeMb == Memcard::MBIT_SIZE_MEMORY_CARD_251) filename.insert(filename.find_last_of("."), ".251"); memorycard = std::make_unique(filename, card_index, sizeMb); @@ -545,9 +545,9 @@ void CEXIMemoryCard::DMARead(u32 _uAddr, u32 _uSize) { memorycard->Read(address, _uSize, Memory::GetPointer(_uAddr)); - if ((address + _uSize) % BLOCK_SIZE == 0) + if ((address + _uSize) % Memcard::BLOCK_SIZE == 0) { - INFO_LOG(EXPANSIONINTERFACE, "reading from block: %x", address / BLOCK_SIZE); + INFO_LOG(EXPANSIONINTERFACE, "reading from block: %x", address / Memcard::BLOCK_SIZE); } // Schedule transfer complete later based on read speed @@ -561,9 +561,9 @@ void CEXIMemoryCard::DMAWrite(u32 _uAddr, u32 _uSize) { memorycard->Write(address, _uSize, Memory::GetPointer(_uAddr)); - if (((address + _uSize) % BLOCK_SIZE) == 0) + if (((address + _uSize) % Memcard::BLOCK_SIZE) == 0) { - INFO_LOG(EXPANSIONINTERFACE, "writing to block: %x", address / BLOCK_SIZE); + INFO_LOG(EXPANSIONINTERFACE, "writing to block: %x", address / Memcard::BLOCK_SIZE); } // Schedule transfer complete later based on write speed diff --git a/Source/Core/Core/HW/GCMemcard/GCIFile.cpp b/Source/Core/Core/HW/GCMemcard/GCIFile.cpp index b173417b8a..9707134749 100644 --- a/Source/Core/Core/HW/GCMemcard/GCIFile.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCIFile.cpp @@ -11,6 +11,8 @@ #include "Common/File.h" #include "Common/Logging/Log.h" +namespace Memcard +{ bool GCIFile::LoadHeader() { if (m_filename.empty()) @@ -100,3 +102,4 @@ void GCIFile::DoState(PointerWrap& p) } p.Do(m_used_blocks); } +} // namespace Memcard diff --git a/Source/Core/Core/HW/GCMemcard/GCIFile.h b/Source/Core/Core/HW/GCMemcard/GCIFile.h index 330c519612..ff3ecb7058 100644 --- a/Source/Core/Core/HW/GCMemcard/GCIFile.h +++ b/Source/Core/Core/HW/GCMemcard/GCIFile.h @@ -12,6 +12,8 @@ class PointerWrap; +namespace Memcard +{ class GCIFile { public: @@ -27,3 +29,4 @@ public: bool m_dirty; std::string m_filename; }; +} // namespace Memcard diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp index a965f3c04a..11676f4faf 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp @@ -31,6 +31,8 @@ static constexpr std::optional BytesToMegabits(u64 bytes) return megabits; } +namespace Memcard +{ bool GCMemcardErrorCode::HasCriticalErrors() const { return Test(GCMemcardValidityIssues::FAILED_TO_OPEN) || Test(GCMemcardValidityIssues::IO_ERROR) || @@ -1744,3 +1746,4 @@ GCMemcardErrorCode Directory::CheckForErrorsWithBat(const BlockAlloc& bat) const return error_code; } +} // namespace Memcard diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h index f772c1214b..71b593134d 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h @@ -24,6 +24,8 @@ namespace File class IOFile; } +namespace Memcard +{ enum { SLOT_A = 0, @@ -489,3 +491,4 @@ public: // reads the animation frames std::optional> ReadAnimRGBA8(u8 index) const; }; +} // namespace Memcard diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h index 6ecbf92c22..9560deae9c 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardBase.h @@ -13,7 +13,7 @@ class PointerWrap; class MemoryCardBase { public: - explicit MemoryCardBase(int card_index = 0, int size_mbits = MBIT_SIZE_MEMORY_CARD_2043) + explicit MemoryCardBase(int card_index = 0, int size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043) : m_card_index(card_index), m_nintendo_card_id(size_mbits) { } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp index 2a737244a6..2cfb80b47b 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp @@ -33,10 +33,10 @@ static const char* MC_HDR = "MC_SYSTEM_AREA"; -bool GCMemcardDirectory::LoadGCI(GCIFile gci) +bool GCMemcardDirectory::LoadGCI(Memcard::GCIFile gci) { // check if any already loaded file has the same internal name as the new file - for (const GCIFile& already_loaded_gci : m_saves) + for (const Memcard::GCIFile& already_loaded_gci : m_saves) { if (gci.m_gci_header.GCI_FileName() == already_loaded_gci.m_gci_header.GCI_FileName()) { @@ -80,8 +80,8 @@ bool GCMemcardDirectory::LoadGCI(GCIFile gci) if (gci.HasCopyProtection()) { - GCMemcard::PSO_MakeSaveGameValid(m_hdr, gci.m_gci_header, gci.m_save_data); - GCMemcard::FZEROGX_MakeSaveGameValid(m_hdr, gci.m_gci_header, gci.m_save_data); + Memcard::GCMemcard::PSO_MakeSaveGameValid(m_hdr, gci.m_gci_header, gci.m_save_data); + Memcard::GCMemcard::FZEROGX_MakeSaveGameValid(m_hdr, gci.m_gci_header, gci.m_save_data); } // actually load save file into memory card @@ -110,10 +110,10 @@ std::vector GCMemcardDirectory::GetFileNamesForGameID(const std::st if (!gci_file) continue; - GCIFile gci; + Memcard::GCIFile gci; gci.m_filename = file_name; gci.m_dirty = false; - if (!gci_file.ReadBytes(&gci.m_gci_header, DENTRY_SIZE)) + if (!gci_file.ReadBytes(&gci.m_gci_header, Memcard::DENTRY_SIZE)) continue; const std::string gci_filename = gci.m_gci_header.GCI_FileName(); @@ -126,9 +126,9 @@ std::vector GCMemcardDirectory::GetFileNamesForGameID(const std::st if (num_blocks > 2043) continue; - const u32 size = num_blocks * BLOCK_SIZE; + const u32 size = num_blocks * Memcard::BLOCK_SIZE; const u64 file_size = gci_file.GetSize(); - if (file_size != size + DENTRY_SIZE) + if (file_size != size + Memcard::DENTRY_SIZE) continue; // There's technically other available block checks to prevent overfilling the virtual memory @@ -153,7 +153,7 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u { // Use existing header data if available { - File::IOFile((m_save_directory + MC_HDR), "rb").ReadBytes(&m_hdr, BLOCK_SIZE); + File::IOFile((m_save_directory + MC_HDR), "rb").ReadBytes(&m_hdr, Memcard::BLOCK_SIZE); } const bool current_game_only = Config::Get(Config::MAIN_GCI_FOLDER_CURRENT_GAME_ONLY); @@ -161,11 +161,11 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u // split up into files for current games we should definitely load, // and files for other games that we don't care too much about - std::vector gci_current_game; - std::vector gci_other_games; + std::vector gci_current_game; + std::vector gci_other_games; for (const std::string& filename : filenames) { - GCIFile gci; + Memcard::GCIFile gci; gci.m_filename = filename; gci.m_dirty = false; if (!gci.LoadHeader()) @@ -180,11 +180,11 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u gci_other_games.emplace_back(std::move(gci)); } - m_saves.reserve(DIRLEN); + m_saves.reserve(Memcard::DIRLEN); // load files for current game size_t failed_loads_current_game = 0; - for (GCIFile& gci : gci_current_game) + for (Memcard::GCIFile& gci : gci_current_game) { if (!LoadGCI(std::move(gci))) { @@ -195,11 +195,11 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u } // leave about 10% of free space on the card if possible - const int total_blocks = m_hdr.m_size_mb * MBIT_TO_BLOCKS - MC_FST_BLOCKS; + const int total_blocks = m_hdr.m_size_mb * Memcard::MBIT_TO_BLOCKS - Memcard::MC_FST_BLOCKS; const int reserved_blocks = total_blocks / 10; // load files for other games - for (GCIFile& gci : gci_other_games) + for (Memcard::GCIFile& gci : gci_other_games) { // leave some free file entries for new saves that might be created if (m_saves.size() > 112) @@ -265,17 +265,17 @@ GCMemcardDirectory::~GCMemcardDirectory() s32 GCMemcardDirectory::Read(u32 src_address, s32 length, u8* dest_address) { - s32 block = src_address / BLOCK_SIZE; - u32 offset = src_address % BLOCK_SIZE; + s32 block = src_address / Memcard::BLOCK_SIZE; + u32 offset = src_address % Memcard::BLOCK_SIZE; s32 extra = 0; // used for read calls that are across multiple blocks - if (offset + length > BLOCK_SIZE) + if (offset + length > Memcard::BLOCK_SIZE) { - extra = length + offset - BLOCK_SIZE; + extra = length + offset - Memcard::BLOCK_SIZE; length -= extra; // verify that we haven't calculated a length beyond BLOCK_SIZE - DEBUG_ASSERT_MSG(EXPANSIONINTERFACE, (src_address + length) % BLOCK_SIZE == 0, + DEBUG_ASSERT_MSG(EXPANSIONINTERFACE, (src_address + length) % Memcard::BLOCK_SIZE == 0, "Memcard directory Read Logic Error"); } @@ -325,17 +325,17 @@ s32 GCMemcardDirectory::Write(u32 dest_address, s32 length, const u8* src_addres std::unique_lock l(m_write_mutex); if (length != 0x80) INFO_LOG(EXPANSIONINTERFACE, "Writing to 0x%x. Length: 0x%x", dest_address, length); - s32 block = dest_address / BLOCK_SIZE; - u32 offset = dest_address % BLOCK_SIZE; + s32 block = dest_address / Memcard::BLOCK_SIZE; + u32 offset = dest_address % Memcard::BLOCK_SIZE; s32 extra = 0; // used for write calls that are across multiple blocks - if (offset + length > BLOCK_SIZE) + if (offset + length > Memcard::BLOCK_SIZE) { - extra = length + offset - BLOCK_SIZE; + extra = length + offset - Memcard::BLOCK_SIZE; length -= extra; // verify that we haven't calculated a length beyond BLOCK_SIZE - DEBUG_ASSERT_MSG(EXPANSIONINTERFACE, (dest_address + length) % BLOCK_SIZE == 0, + DEBUG_ASSERT_MSG(EXPANSIONINTERFACE, (dest_address + length) % Memcard::BLOCK_SIZE == 0, "Memcard directory Write Logic Error"); } if (m_last_block != block) @@ -353,7 +353,7 @@ s32 GCMemcardDirectory::Write(u32 dest_address, s32 length, const u8* src_addres s32 bytes_written = 0; while (length > 0) { - s32 to_write = std::min(DENTRY_SIZE, length); + s32 to_write = std::min(Memcard::DENTRY_SIZE, length); bytes_written += DirectoryWrite(dest_address + bytes_written, to_write, src_address + bytes_written); length -= to_write; @@ -383,20 +383,20 @@ s32 GCMemcardDirectory::Write(u32 dest_address, s32 length, const u8* src_addres l.unlock(); if (extra) extra = Write(dest_address + length, extra, src_address + length); - if (offset + length == BLOCK_SIZE) + if (offset + length == Memcard::BLOCK_SIZE) m_flush_trigger.Set(); return length + extra; } void GCMemcardDirectory::ClearBlock(u32 address) { - if (address % BLOCK_SIZE) + if (address % Memcard::BLOCK_SIZE) { PanicAlertT("GCMemcardDirectory: ClearBlock called with invalid block address"); return; } - u32 block = address / BLOCK_SIZE; + u32 block = address / Memcard::BLOCK_SIZE; INFO_LOG(EXPANSIONINTERFACE, "Clearing block %u", block); switch (block) { @@ -425,34 +425,34 @@ void GCMemcardDirectory::ClearBlock(u32 address) if (m_last_block == -1) return; } - ((GCMBlock*)m_last_block_address)->Erase(); + ((Memcard::GCMBlock*)m_last_block_address)->Erase(); } inline void GCMemcardDirectory::SyncSaves() { - Directory* current = &m_dir2; + Memcard::Directory* current = &m_dir2; if (m_dir1.m_update_counter > m_dir2.m_update_counter) { current = &m_dir1; } - for (u32 i = 0; i < DIRLEN; ++i) + for (u32 i = 0; i < Memcard::DIRLEN; ++i) { - if (current->m_dir_entries[i].m_gamecode != DEntry::UNINITIALIZED_GAMECODE) + if (current->m_dir_entries[i].m_gamecode != Memcard::DEntry::UNINITIALIZED_GAMECODE) { INFO_LOG(EXPANSIONINTERFACE, "Syncing save 0x%x", Common::swap32(current->m_dir_entries[i].m_gamecode.data())); bool added = false; while (i >= m_saves.size()) { - GCIFile temp; + Memcard::GCIFile temp; m_saves.push_back(temp); 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]), + Memcard::DENTRY_SIZE)) { m_saves[i].m_dirty = true; const u32 gamecode = Common::swap32(m_saves[i].m_gci_header.m_gamecode.data()); @@ -466,7 +466,8 @@ inline void GCMemcardDirectory::SyncSaves() Common::swap32(m_saves[i].m_gci_header.m_gamecode.data()), Common::swap32(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]), + Memcard::DENTRY_SIZE); if (old_start != new_start) { INFO_LOG(EXPANSIONINTERFACE, "Save moved from 0x%x to 0x%x", old_start, new_start); @@ -483,7 +484,7 @@ inline void GCMemcardDirectory::SyncSaves() { INFO_LOG(EXPANSIONINTERFACE, "Clearing and/or deleting save 0x%x", Common::swap32(m_saves[i].m_gci_header.m_gamecode.data())); - m_saves[i].m_gci_header.m_gamecode = DEntry::UNINITIALIZED_GAMECODE; + m_saves[i].m_gci_header.m_gamecode = Memcard::DEntry::UNINITIALIZED_GAMECODE; m_saves[i].m_save_data.clear(); m_saves[i].m_used_blocks.clear(); m_saves[i].m_dirty = true; @@ -494,7 +495,7 @@ inline s32 GCMemcardDirectory::SaveAreaRW(u32 block, bool writing) { for (u16 i = 0; i < m_saves.size(); ++i) { - if (m_saves[i].m_gci_header.m_gamecode != DEntry::UNINITIALIZED_GAMECODE) + if (m_saves[i].m_gci_header.m_gamecode != Memcard::DEntry::UNINITIALIZED_GAMECODE) { if (m_saves[i].m_used_blocks.empty()) { @@ -530,12 +531,12 @@ inline s32 GCMemcardDirectory::SaveAreaRW(u32 block, bool writing) s32 GCMemcardDirectory::DirectoryWrite(u32 dest_address, u32 length, const u8* src_address) { - u32 block = dest_address / BLOCK_SIZE; - u32 offset = dest_address % BLOCK_SIZE; - Directory* dest = (block == 1) ? &m_dir1 : &m_dir2; - u16 Dnum = offset / DENTRY_SIZE; + u32 block = dest_address / Memcard::BLOCK_SIZE; + u32 offset = dest_address % Memcard::BLOCK_SIZE; + Memcard::Directory* dest = (block == 1) ? &m_dir1 : &m_dir2; + u16 Dnum = offset / Memcard::DENTRY_SIZE; - if (Dnum == DIRLEN) + if (Dnum == Memcard::DIRLEN) { // first 58 bytes should always be 0xff // needed to update the update ctr, checksums @@ -551,7 +552,7 @@ s32 GCMemcardDirectory::DirectoryWrite(u32 dest_address, u32 length, const u8* s bool GCMemcardDirectory::SetUsedBlocks(int save_index) { - BlockAlloc* current_bat; + Memcard::BlockAlloc* current_bat; if (m_bat2.m_update_counter > m_bat1.m_update_counter) current_bat = &m_bat2; else @@ -586,12 +587,12 @@ void GCMemcardDirectory::FlushToFile() { std::unique_lock l(m_write_mutex); int errors = 0; - DEntry invalid; + Memcard::DEntry invalid; for (u16 i = 0; i < m_saves.size(); ++i) { if (m_saves[i].m_dirty) { - if (m_saves[i].m_gci_header.m_gamecode != DEntry::UNINITIALIZED_GAMECODE) + if (m_saves[i].m_gci_header.m_gamecode != Memcard::DEntry::UNINITIALIZED_GAMECODE) { m_saves[i].m_dirty = false; if (m_saves[i].m_save_data.empty()) @@ -622,8 +623,9 @@ void GCMemcardDirectory::FlushToFile() File::IOFile gci(m_saves[i].m_filename, "wb"); if (gci) { - gci.WriteBytes(&m_saves[i].m_gci_header, DENTRY_SIZE); - gci.WriteBytes(m_saves[i].m_save_data.data(), BLOCK_SIZE * m_saves[i].m_save_data.size()); + gci.WriteBytes(&m_saves[i].m_gci_header, Memcard::DENTRY_SIZE); + gci.WriteBytes(m_saves[i].m_save_data.data(), + Memcard::BLOCK_SIZE * m_saves[i].m_save_data.size()); if (gci.IsGood()) { @@ -681,11 +683,11 @@ void GCMemcardDirectory::DoState(PointerWrap& p) m_last_block = -1; m_last_block_address = nullptr; p.Do(m_save_directory); - p.DoPOD
(m_hdr); - p.DoPOD(m_dir1); - p.DoPOD(m_dir2); - p.DoPOD(m_bat1); - p.DoPOD(m_bat2); + p.DoPOD(m_hdr); + p.DoPOD(m_dir1); + p.DoPOD(m_dir2); + p.DoPOD(m_bat1); + p.DoPOD(m_bat2); int num_saves = (int)m_saves.size(); p.Do(num_saves); m_saves.resize(num_saves); @@ -702,10 +704,10 @@ void MigrateFromMemcardFile(const std::string& directory_name, int card_index) Config::Get(Config::MAIN_MEMCARD_B_PATH); if (File::Exists(ini_memcard)) { - auto [error_code, memcard] = GCMemcard::Open(ini_memcard.c_str()); + auto [error_code, memcard] = Memcard::GCMemcard::Open(ini_memcard.c_str()); if (!error_code.HasCriticalErrors() && memcard && memcard->IsValid()) { - for (u8 i = 0; i < DIRLEN; i++) + for (u8 i = 0; i < Memcard::DIRLEN; i++) { memcard->ExportGci(i, "", directory_name); } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h index f3fe9ddaa0..dbda7b3778 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h @@ -41,7 +41,7 @@ public: void DoState(PointerWrap& p) override; private: - bool LoadGCI(GCIFile gci); + bool LoadGCI(Memcard::GCIFile gci); inline s32 SaveAreaRW(u32 block, bool writing = false); // s32 DirectoryRead(u32 offset, u32 length, u8* dest_address); s32 DirectoryWrite(u32 dest_address, u32 length, const u8* src_address); @@ -52,10 +52,12 @@ private: s32 m_last_block; u8* m_last_block_address; - Header m_hdr; - Directory m_dir1, m_dir2; - BlockAlloc m_bat1, m_bat2; - std::vector m_saves; + Memcard::Header m_hdr; + Memcard::Directory m_dir1; + Memcard::Directory m_dir2; + Memcard::BlockAlloc m_bat1; + Memcard::BlockAlloc m_bat2; + std::vector m_saves; std::string m_save_directory; Common::Event m_flush_trigger; diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp index 628e85efc1..90d715eedd 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp @@ -52,8 +52,8 @@ MemoryCard::MemoryCard(const std::string& filename, int card_index, u16 size_mbi m_memcard_data = std::make_unique(m_memory_card_size); // Fills in MC_HDR_SIZE bytes - GCMemcard::Format(&m_memcard_data[0], m_filename.find(".JAP.raw") != std::string::npos, - size_mbits); + Memcard::GCMemcard::Format(&m_memcard_data[0], m_filename.find(".JAP.raw") != std::string::npos, + size_mbits); memset(&m_memcard_data[MC_HDR_SIZE], 0xFF, m_memory_card_size - MC_HDR_SIZE); INFO_LOG(EXPANSIONINTERFACE, "No memory card found. A new one was created instead."); @@ -227,7 +227,7 @@ s32 MemoryCard::Write(u32 dest_address, s32 length, const u8* src_address) void MemoryCard::ClearBlock(u32 address) { - if (address & (BLOCK_SIZE - 1) || !IsAddressInBounds(address)) + if (address & (Memcard::BLOCK_SIZE - 1) || !IsAddressInBounds(address)) { PanicAlertT("MemoryCard: ClearBlock called on invalid address (0x%x)", address); return; @@ -235,7 +235,7 @@ void MemoryCard::ClearBlock(u32 address) else { std::unique_lock l(m_flush_mutex); - memset(&m_memcard_data[address], 0xFF, BLOCK_SIZE); + memset(&m_memcard_data[address], 0xFF, Memcard::BLOCK_SIZE); } MakeDirty(); } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h index f04034f340..e62795e6b0 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h @@ -19,7 +19,7 @@ class MemoryCard : public MemoryCardBase { public: MemoryCard(const std::string& filename, int card_index, - u16 size_mbits = MBIT_SIZE_MEMORY_CARD_2043); + u16 size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043); ~MemoryCard(); static void CheckPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA); void FlushThread(); diff --git a/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp index a7041c4dd5..36a12627f4 100644 --- a/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp +++ b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp @@ -75,7 +75,7 @@ bool GCMemcardCreateNewDialog::CreateCard() return false; const std::string p = path.toStdString(); - auto memcard = GCMemcard::Create(p, size, is_shift_jis); + auto memcard = Memcard::GCMemcard::Create(p, size, is_shift_jis); if (memcard && memcard->Save()) { m_card_path = p; diff --git a/Source/Core/DolphinQt/GCMemcardManager.cpp b/Source/Core/DolphinQt/GCMemcardManager.cpp index 6a20522980..60dd5ece79 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.cpp +++ b/Source/Core/DolphinQt/GCMemcardManager.cpp @@ -248,7 +248,7 @@ void GCMemcardManager::UpdateSlotTable(int slot) m_slot_stat_label[slot]->setText(tr("%1 Free Blocks; %2 Free Dir Entries") .arg(memcard->GetFreeBlocks()) - .arg(DIRLEN - memcard->GetNumFiles())); + .arg(Memcard::DIRLEN - memcard->GetNumFiles())); } void GCMemcardManager::UpdateActions() @@ -268,12 +268,12 @@ void GCMemcardManager::UpdateActions() void GCMemcardManager::SetSlotFile(int slot, QString path) { - auto [error_code, memcard] = GCMemcard::Open(path.toStdString()); + auto [error_code, memcard] = Memcard::GCMemcard::Open(path.toStdString()); if (!error_code.HasCriticalErrors() && memcard && memcard->IsValid()) { m_slot_file_edit[slot]->setText(path); - m_slot_memcard[slot] = std::make_unique(std::move(*memcard)); + m_slot_memcard[slot] = std::make_unique(std::move(*memcard)); } else { @@ -336,7 +336,7 @@ void GCMemcardManager::ExportFiles(bool prompt) // TODO: This is obviously intended to check for success instead. const auto exportRetval = memcard->ExportGci(file_index, path.toStdString(), ""); - if (exportRetval == GCMemcardExportFileRetVal::UNUSED) + if (exportRetval == Memcard::GCMemcardExportFileRetVal::UNUSED) { File::Delete(path.toStdString()); } @@ -366,7 +366,7 @@ void GCMemcardManager::ImportFile() const auto result = m_slot_memcard[m_active_slot]->ImportGci(path.toStdString()); - if (result != GCMemcardImportFileRetVal::SUCCESS) + if (result != Memcard::GCMemcardImportFileRetVal::SUCCESS) { ModalMessageBox::critical(this, tr("Import failed"), tr("Failed to import \"%1\".").arg(path)); return; @@ -392,7 +392,7 @@ void GCMemcardManager::CopyFiles() const auto result = m_slot_memcard[!m_active_slot]->CopyFrom(*memcard, file_index); - if (result != GCMemcardImportFileRetVal::SUCCESS) + if (result != Memcard::GCMemcardImportFileRetVal::SUCCESS) { ModalMessageBox::warning(this, tr("Copy failed"), tr("Failed to copy file")); } @@ -436,7 +436,7 @@ void GCMemcardManager::DeleteFiles() for (int file_index : file_indices) { - if (memcard->RemoveFile(file_index) != GCMemcardRemoveFileRetVal::SUCCESS) + if (memcard->RemoveFile(file_index) != Memcard::GCMemcardRemoveFileRetVal::SUCCESS) { ModalMessageBox::warning(this, tr("Remove failed"), tr("Failed to remove file")); } @@ -522,8 +522,8 @@ QPixmap GCMemcardManager::GetBannerFromSaveFile(int file_index, int slot) QImage image; if (pxdata) { - image = QImage(reinterpret_cast(pxdata->data()), MEMORY_CARD_BANNER_WIDTH, - MEMORY_CARD_BANNER_HEIGHT, QImage::Format_ARGB32); + image = QImage(reinterpret_cast(pxdata->data()), Memcard::MEMORY_CARD_BANNER_WIDTH, + Memcard::MEMORY_CARD_BANNER_HEIGHT, QImage::Format_ARGB32); } return QPixmap::fromImage(image); @@ -545,7 +545,8 @@ GCMemcardManager::IconAnimationData GCMemcardManager::GetIconFromSaveFile(int fi for (size_t f = 0; f < decoded_data->size(); ++f) { QImage img(reinterpret_cast((*decoded_data)[f].image_data.data()), - MEMORY_CARD_ICON_WIDTH, MEMORY_CARD_ICON_HEIGHT, QImage::Format_ARGB32); + Memcard::MEMORY_CARD_ICON_WIDTH, Memcard::MEMORY_CARD_ICON_HEIGHT, + QImage::Format_ARGB32); frame_data.m_frames.push_back(QPixmap::fromImage(img)); for (int i = 0; i < (*decoded_data)[f].delay; ++i) { @@ -579,32 +580,32 @@ GCMemcardManager::IconAnimationData GCMemcardManager::GetIconFromSaveFile(int fi return frame_data; } -QString GCMemcardManager::GetErrorMessagesForErrorCode(const GCMemcardErrorCode& code) +QString GCMemcardManager::GetErrorMessagesForErrorCode(const Memcard::GCMemcardErrorCode& code) { QStringList sl; - if (code.Test(GCMemcardValidityIssues::FAILED_TO_OPEN)) + if (code.Test(Memcard::GCMemcardValidityIssues::FAILED_TO_OPEN)) sl.push_back(tr("Couldn't open file.")); - if (code.Test(GCMemcardValidityIssues::IO_ERROR)) + if (code.Test(Memcard::GCMemcardValidityIssues::IO_ERROR)) sl.push_back(tr("Couldn't read file.")); - if (code.Test(GCMemcardValidityIssues::INVALID_CARD_SIZE)) + if (code.Test(Memcard::GCMemcardValidityIssues::INVALID_CARD_SIZE)) sl.push_back(tr("Filesize does not match any known GameCube Memory Card size.")); - if (code.Test(GCMemcardValidityIssues::MISMATCHED_CARD_SIZE)) + if (code.Test(Memcard::GCMemcardValidityIssues::MISMATCHED_CARD_SIZE)) sl.push_back(tr("Filesize in header mismatches actual card size.")); - if (code.Test(GCMemcardValidityIssues::INVALID_CHECKSUM)) + if (code.Test(Memcard::GCMemcardValidityIssues::INVALID_CHECKSUM)) sl.push_back(tr("Invalid checksums.")); - if (code.Test(GCMemcardValidityIssues::FREE_BLOCK_MISMATCH)) + if (code.Test(Memcard::GCMemcardValidityIssues::FREE_BLOCK_MISMATCH)) sl.push_back(tr("Mismatch between free block count in header and actually unused blocks.")); - if (code.Test(GCMemcardValidityIssues::DIR_BAT_INCONSISTENT)) + if (code.Test(Memcard::GCMemcardValidityIssues::DIR_BAT_INCONSISTENT)) sl.push_back(tr("Mismatch between internal data structures.")); - if (code.Test(GCMemcardValidityIssues::DATA_IN_UNUSED_AREA)) + if (code.Test(Memcard::GCMemcardValidityIssues::DATA_IN_UNUSED_AREA)) sl.push_back(tr("Data in area of file that should be unused.")); if (sl.empty()) diff --git a/Source/Core/DolphinQt/GCMemcardManager.h b/Source/Core/DolphinQt/GCMemcardManager.h index ccacf98c2c..c7e2202474 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.h +++ b/Source/Core/DolphinQt/GCMemcardManager.h @@ -13,8 +13,11 @@ #include "Common/CommonTypes.h" +namespace Memcard +{ class GCMemcard; class GCMemcardErrorCode; +} // namespace Memcard class QDialogButtonBox; class QGroupBox; @@ -33,7 +36,7 @@ public: explicit GCMemcardManager(QWidget* parent = nullptr); ~GCMemcardManager(); - static QString GetErrorMessagesForErrorCode(const GCMemcardErrorCode& code); + static QString GetErrorMessagesForErrorCode(const Memcard::GCMemcardErrorCode& code); private: struct IconAnimationData; @@ -73,7 +76,7 @@ private: // Slots static constexpr int SLOT_COUNT = 2; std::array, SLOT_COUNT> m_slot_active_icons; - std::array, SLOT_COUNT> m_slot_memcard; + std::array, SLOT_COUNT> m_slot_memcard; std::array m_slot_group; std::array m_slot_file_edit; std::array m_slot_open_button; diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 6700984ac7..1304793432 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -210,7 +210,7 @@ void GameCubePane::OnConfigPressed(int slot) { if (File::Exists(filename.toStdString())) { - auto [error_code, mc] = GCMemcard::Open(filename.toStdString()); + auto [error_code, mc] = Memcard::GCMemcard::Open(filename.toStdString()); if (error_code.HasCriticalErrors() || !mc || !mc->IsValid()) {