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/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 e650429b81..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, @@ -158,28 +160,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(); @@ -511,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 new file mode 100644 index 0000000000..9560deae9c --- /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 = Memcard::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.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 2869ba2d32..dbda7b3778 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 @@ -40,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); @@ -51,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 727d625aa4..e62795e6b0 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; @@ -18,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()) {