diff --git a/Data/Sys/GameSettings/GDK.ini b/Data/Sys/GameSettings/GDK.ini index 6b758de9dd..c1a0a4c187 100644 --- a/Data/Sys/GameSettings/GDK.ini +++ b/Data/Sys/GameSettings/GDK.ini @@ -4,7 +4,7 @@ # Values set here will override the main Dolphin settings. # This game does not work properly with large memorycards, use a 251 block card # see https://www.nintendo.com/consumer/memorycard1019.jsp -MemoryCard251 = True +MemoryCardSize = 2 [OnLoad] # Add memory patches to be loaded once on boot here. diff --git a/Data/Sys/GameSettings/GDQ.ini b/Data/Sys/GameSettings/GDQ.ini index 5294de158a..29a97d93da 100644 --- a/Data/Sys/GameSettings/GDQ.ini +++ b/Data/Sys/GameSettings/GDQ.ini @@ -4,7 +4,7 @@ # Values set here will override the main Dolphin settings. # This game does not work properly with large memorycards, use a 251 block card # see https://www.nintendo.com/consumer/memorycard1019.jsp -MemoryCard251 = True +MemoryCardSize = 2 [OnLoad] # Add memory patches to be loaded once on boot here. diff --git a/Data/Sys/GameSettings/GDX.ini b/Data/Sys/GameSettings/GDX.ini index 079e54202b..ca9f6464e5 100644 --- a/Data/Sys/GameSettings/GDX.ini +++ b/Data/Sys/GameSettings/GDX.ini @@ -2,4 +2,4 @@ [Core] # Values set here will override the main Dolphin settings. -MemoryCard251 = True +MemoryCardSize = 2 diff --git a/Data/Sys/GameSettings/GWL.ini b/Data/Sys/GameSettings/GWL.ini index 415a470b03..d34f953397 100644 --- a/Data/Sys/GameSettings/GWL.ini +++ b/Data/Sys/GameSettings/GWL.ini @@ -2,7 +2,7 @@ [Core] # Values set here will override the main Dolphin settings. -MemoryCard251 = True +MemoryCardSize = 2 [OnLoad] # Add memory patches to be loaded once on boot here. @@ -14,4 +14,4 @@ MemoryCard251 = True # Add action replay cheats here. [Video_Hacks] -ImmediateXFBEnable = False \ No newline at end of file +ImmediateXFBEnable = False diff --git a/Data/Sys/GameSettings/GWT.ini b/Data/Sys/GameSettings/GWT.ini index 422b26e6dd..1be2190eeb 100644 --- a/Data/Sys/GameSettings/GWT.ini +++ b/Data/Sys/GameSettings/GWT.ini @@ -4,7 +4,7 @@ # Values set here will override the main Dolphin settings. # This game does not work properly with large memorycards, use a 251 block card # see https://www.nintendo.com/consumer/memorycard1019.jsp -MemoryCard251 = True +MemoryCardSize = 2 CPUThread = False [OnLoad] diff --git a/Source/Core/Core/HW/EXI/EXI.cpp b/Source/Core/Core/HW/EXI/EXI.cpp index 0c11ad8e05..4e42384c15 100644 --- a/Source/Core/Core/HW/EXI/EXI.cpp +++ b/Source/Core/Core/HW/EXI/EXI.cpp @@ -75,11 +75,12 @@ void Init() CEXIMemoryCard::Init(); { - bool use_memcard_251; + u16 size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043; + int size_override; IniFile gameIni = SConfig::GetInstance().LoadGameIni(); - gameIni.GetOrCreateSection("Core")->Get("MemoryCard251", &use_memcard_251, false); - const u16 size_mbits = - use_memcard_251 ? Memcard::MBIT_SIZE_MEMORY_CARD_251 : Memcard::MBIT_SIZE_MEMORY_CARD_2043; + gameIni.GetOrCreateSection("Core")->Get("MemoryCardSize", &size_override, -1); + if (size_override >= 0 && size_override <= 4) + size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_59 << size_override; const bool shift_jis = SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region) == DiscIO::Region::NTSC_J; const CardFlashId& flash_id = g_SRAM.settings_ex.flash_id[Memcard::SLOT_A]; diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp index f00e6c486e..06a47d36e1 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp @@ -236,8 +236,11 @@ void CEXIMemoryCard::SetupRawMemcard(u16 size_mb) SConfig::GetDirectoryForRegion(SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region)); MemoryCard::CheckPath(filename, region_dir, is_slot_a); - if (size_mb == Memcard::MBIT_SIZE_MEMORY_CARD_251) - filename.insert(filename.find_last_of('.'), ".251"); + if (size_mb < Memcard::MBIT_SIZE_MEMORY_CARD_2043) + { + filename.insert(filename.find_last_of('.'), + fmt::format(".{}", Memcard::MbitToFreeBlocks(size_mb))); + } m_memory_card = std::make_unique(filename, m_card_index, size_mb); } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp index 8596c1f568..58882ad4bf 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp @@ -673,7 +673,7 @@ std::optional GCMemcard::GetDEntry(u8 index) const BlockAlloc::BlockAlloc(u16 size_mbits) { memset(this, 0, BLOCK_SIZE); - m_free_blocks = (size_mbits * MBIT_TO_BLOCKS) - MC_FST_BLOCKS; + m_free_blocks = MbitToFreeBlocks(size_mbits); m_last_allocated_block = 4; FixChecksums(); } diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h index 0cea51a017..bd238b5977 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h @@ -141,6 +141,11 @@ 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; +constexpr u32 MbitToFreeBlocks(u16 size_mb) +{ + return size_mb * MBIT_TO_BLOCKS - MC_FST_BLOCKS; +} + struct GCMBlock { GCMBlock(); diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp index 9699eddf2b..a9bac23577 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp @@ -203,8 +203,7 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, } // leave about 10% of free space on the card if possible - const int total_blocks = - m_hdr.m_data.m_size_mb * Memcard::MBIT_TO_BLOCKS - Memcard::MC_FST_BLOCKS; + const int total_blocks = Memcard::MbitToFreeBlocks(m_hdr.m_data.m_size_mb); const int reserved_blocks = total_blocks / 10; // load files for other games diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index f073e70f17..9269e69d71 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -39,6 +39,7 @@ #include "Core/ConfigManager.h" #include "Core/GeckoCode.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" +#include "Core/HW/GCMemcard/GCMemcard.h" #include "Core/HW/SI/SI.h" #include "Core/HW/SI/SI_Device.h" #include "Core/HW/SI/SI_DeviceGCController.h" @@ -856,8 +857,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) bool is_slot_a; std::string region; - bool mc251; - packet >> is_slot_a >> region >> mc251; + int size_override; + packet >> is_slot_a >> region >> size_override; // This check is mainly intended to filter out characters which have special meanings in paths if (region != JAP_DIR && region != USA_DIR && region != EUR_DIR) @@ -866,8 +867,15 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) return 0; } + std::string size_suffix; + if (size_override >= 0 && size_override <= 4) + { + size_suffix = fmt::format( + ".{}", Memcard::MbitToFreeBlocks(Memcard::MBIT_SIZE_MEMORY_CARD_59 << size_override)); + } + const std::string path = File::GetUserPath(D_GCUSER_IDX) + GC_MEMCARD_NETPLAY + - (is_slot_a ? "A." : "B.") + region + (mc251 ? ".251" : "") + ".raw"; + (is_slot_a ? "A." : "B.") + region + size_suffix + ".raw"; if (File::Exists(path) && !File::Delete(path)) { PanicAlertFmtT("Failed to delete NetPlay memory card. Verify your write permissions."); diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 2695703ca5..cb47d292a1 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -41,6 +41,7 @@ #include "Core/ConfigManager.h" #include "Core/GeckoCode.h" #include "Core/GeckoCodeConfig.h" +#include "Core/HW/GCMemcard/GCMemcard.h" #include "Core/HW/GCMemcard/GCMemcardDirectory.h" #include "Core/HW/GCMemcard/GCMemcardRaw.h" #include "Core/HW/Sram.h" @@ -1572,17 +1573,21 @@ bool NetPlayServer::SyncSaveData() MemoryCard::CheckPath(path, region, is_slot_a); - bool mc251; + int size_override; IniFile gameIni = SConfig::LoadGameIni(game->GetGameID(), game->GetRevision()); - gameIni.GetOrCreateSection("Core")->Get("MemoryCard251", &mc251, false); + gameIni.GetOrCreateSection("Core")->Get("MemoryCardSize", &size_override, -1); - if (mc251) - path.insert(path.find_last_of('.'), ".251"); + if (size_override >= 0 && size_override <= 4) + { + path.insert(path.find_last_of('.'), + fmt::format(".{}", Memcard::MbitToFreeBlocks(Memcard::MBIT_SIZE_MEMORY_CARD_59 + << size_override))); + } sf::Packet pac; pac << static_cast(NP_MSG_SYNC_SAVE_DATA); pac << static_cast(SYNC_SAVE_DATA_RAW); - pac << is_slot_a << region << mc251; + pac << is_slot_a << region << size_override; if (File::Exists(path)) {