diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp index 65c35b12b4..b149b07cf4 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -158,10 +159,34 @@ CEXIMemoryCard::CEXIMemoryCard(const int index, bool gciFolder) : card_index(ind SetCardFlashID(header.data(), card_index); } +std::pair +CEXIMemoryCard::GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_folder) +{ + std::string path_override = + Config::Get(card_index == 0 ? Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE : + Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE); + + if (!path_override.empty()) + return {std::move(path_override), false}; + + std::string path = File::GetUserPath(D_GCUSER_IDX); + + const bool use_movie_folder = allow_movie_folder == AllowMovieFolder::Yes && + Movie::IsPlayingInput() && Movie::IsConfigSaved() && + Movie::IsUsingMemcard(card_index) && + Movie::IsStartingFromClearSave(); + + if (use_movie_folder) + path += "Movie" DIR_SEP; + + const DiscIO::Region region = SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region); + path = path + SConfig::GetDirectoryForRegion(region) + DIR_SEP + + fmt::format("Card {}", char('A' + card_index)); + return {std::move(path), !use_movie_folder}; +} + void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) { - const DiscIO::Region region = SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region); - const std::string& game_id = SConfig::GetInstance().GetGameID(); u32 CurrentGameId = 0; if (game_id.length() >= 4 && game_id != "00000000" && @@ -170,32 +195,10 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) CurrentGameId = Common::swap32(reinterpret_cast(game_id.c_str())); } - const bool shift_jis = region == DiscIO::Region::NTSC_J; + const bool shift_jis = + SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region) == DiscIO::Region::NTSC_J; - std::string strDirectoryName = File::GetUserPath(D_GCUSER_IDX); - - bool migrate = true; - - if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(card_index) && - Movie::IsStartingFromClearSave()) - { - strDirectoryName += "Movie" DIR_SEP; - migrate = false; - } - - const std::string path_override = - Config::Get(card_index == 0 ? Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE : - Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE); - if (!path_override.empty()) - { - strDirectoryName = path_override; - migrate = false; - } - else - { - strDirectoryName = strDirectoryName + SConfig::GetDirectoryForRegion(region) + DIR_SEP + - fmt::format("Card {}", char('A' + card_index)); - } + const auto [strDirectoryName, migrate] = GetGCIFolderPath(card_index, AllowMovieFolder::Yes); const File::FileInfo file_info(strDirectoryName); if (!file_info.Exists()) diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h index 2ac1811515..4075637f25 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "Core/HW/EXI/EXI_Device.h" @@ -14,6 +16,12 @@ class PointerWrap; namespace ExpansionInterface { +enum class AllowMovieFolder +{ + Yes, + No, +}; + class CEXIMemoryCard : public IEXIDevice { public: @@ -34,6 +42,9 @@ public: static void Init(); static void Shutdown(); + static std::pair + GetGCIFolderPath(int card_index, AllowMovieFolder allow_movie_folder); + private: void SetupGciFolder(u16 sizeMb); void SetupRawMemcard(u16 sizeMb); diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index f85c625016..377bfd4c4b 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -44,6 +44,7 @@ #include "Core/HW/CPU.h" #include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" +#include "Core/HW/EXI/EXI_DeviceMemoryCard.h" #include "Core/HW/ProcessorInterface.h" #include "Core/HW/SI/SI.h" #include "Core/HW/SI/SI_Device.h" @@ -1379,6 +1380,15 @@ void SetGraphicsConfig() // NOTE: EmuThread / Host Thread void GetSettings() { + const bool slot_a_has_raw_memcard = + SConfig::GetInstance().m_EXIDevice[0] == ExpansionInterface::EXIDEVICE_MEMORYCARD; + const bool slot_a_has_gci_folder = + SConfig::GetInstance().m_EXIDevice[0] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER; + const bool slot_b_has_raw_memcard = + SConfig::GetInstance().m_EXIDevice[1] == ExpansionInterface::EXIDEVICE_MEMORYCARD; + const bool slot_b_has_gci_folder = + SConfig::GetInstance().m_EXIDevice[1] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER; + s_bSaveConfig = true; s_bNetPlay = NetPlay::IsNetPlayRunning(); if (SConfig::GetInstance().bWii) @@ -1389,16 +1399,21 @@ void GetSettings() } else { - s_bClearSave = !File::Exists(Config::Get(Config::MAIN_MEMCARD_A_PATH)); + const auto gci_folder_has_saves = [](int card_index) { + const auto [path, migrate] = ExpansionInterface::CEXIMemoryCard::GetGCIFolderPath( + card_index, ExpansionInterface::AllowMovieFolder::No); + const u64 number_of_saves = File::ScanDirectoryTree(path, false).size; + return number_of_saves > 0; + }; + + s_bClearSave = + !(slot_a_has_raw_memcard && File::Exists(Config::Get(Config::MAIN_MEMCARD_A_PATH))) && + !(slot_b_has_raw_memcard && File::Exists(Config::Get(Config::MAIN_MEMCARD_B_PATH))) && + !(slot_a_has_gci_folder && gci_folder_has_saves(0)) && + !(slot_b_has_gci_folder && gci_folder_has_saves(1)); } - s_memcards |= - (SConfig::GetInstance().m_EXIDevice[0] == ExpansionInterface::EXIDEVICE_MEMORYCARD || - SConfig::GetInstance().m_EXIDevice[0] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER) - << 0; - s_memcards |= - (SConfig::GetInstance().m_EXIDevice[1] == ExpansionInterface::EXIDEVICE_MEMORYCARD || - SConfig::GetInstance().m_EXIDevice[1] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER) - << 1; + s_memcards |= (slot_a_has_raw_memcard || slot_a_has_gci_folder) << 0; + s_memcards |= (slot_b_has_raw_memcard || slot_b_has_gci_folder) << 1; s_revision = ConvertGitRevisionToBytes(Common::scm_rev_git_str);