System: Simplify memory card opening

Now cards no longer reopen when changing discs in a multi-disc game.
old-dev
Stenzek 1 month ago
parent 790ac23515
commit c2bbef066d
No known key found for this signature in database

@ -295,10 +295,10 @@ std::unique_ptr<MemoryCard> MemoryCard::Create()
return mc;
}
std::unique_ptr<MemoryCard> MemoryCard::Open(std::string_view path)
std::unique_ptr<MemoryCard> MemoryCard::Open(std::string path)
{
std::unique_ptr<MemoryCard> mc = std::make_unique<MemoryCard>();
mc->m_path = path;
mc->m_path = std::move(path);
Error error;
if (!FileSystem::FileExists(mc->m_path.c_str())) [[unlikely]]

@ -23,7 +23,7 @@ public:
static constexpr u32 STATE_SIZE = 1 + 1 + 2 + 1 + 1 + 1 + MemoryCardImage::DATA_SIZE + 1;
static std::unique_ptr<MemoryCard> Create();
static std::unique_ptr<MemoryCard> Open(std::string_view path);
static std::unique_ptr<MemoryCard> Open(std::string path);
const MemoryCardImage::DataArray& GetData() const { return m_data; }
MemoryCardImage::DataArray& GetData() { return m_data; }

@ -2591,7 +2591,7 @@ void EmuFolders::Update()
System::ReloadGameSettings(false);
if (System::IsValid() && old_memorycards != EmuFolders::MemoryCards)
System::UpdateMemoryCardTypes();
System::UpdateMemoryCards();
}
void EmuFolders::EnsureFolderExists(const std::string& path)

@ -203,8 +203,7 @@ static std::string_view GetCurrentGameSaveTitle();
static void UpdateControllers();
static void ResetControllers();
static void ReloadMemoryCardsFromGameChange();
static std::unique_ptr<MemoryCard> GetMemoryCardForSlot(u32 slot, MemoryCardType type);
static std::string GetMemoryCardPathForSlot(u32 slot, MemoryCardType type);
static void UpdateMultitaps();
static std::string GetMediaPathFromSaveState(const char* path);
@ -1859,7 +1858,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
s_state.exe_override = std::move(exe_override);
UpdateControllers();
UpdateMemoryCardTypes();
UpdateMemoryCards();
UpdateMultitaps();
InternalReset();
@ -3787,170 +3786,40 @@ void System::ResetControllers()
}
}
std::unique_ptr<MemoryCard> System::GetMemoryCardForSlot(u32 slot, MemoryCardType type)
{
// Disable memory cards when running PSFs.
const bool is_running_psf = !s_state.running_game_path.empty() && IsPsfPath(s_state.running_game_path.c_str());
if (is_running_psf)
return nullptr;
std::string message_key = fmt::format("MemoryCard{}SharedWarning", slot);
switch (type)
{
case MemoryCardType::PerGame:
{
if (s_state.running_game_serial.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no code. Using shared card instead."),
slot + 1u),
Host::OSD_INFO_DURATION);
return MemoryCard::Open(g_settings.GetSharedMemoryCardPath(slot));
}
else
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
return MemoryCard::Open(g_settings.GetGameMemoryCardPath(s_state.running_game_serial, slot));
}
}
case MemoryCardType::PerGameTitle:
{
if (s_state.running_game_title.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no title. Using shared card instead."),
slot + 1u),
Host::OSD_INFO_DURATION);
return MemoryCard::Open(g_settings.GetSharedMemoryCardPath(slot));
}
else
{
const std::string_view game_title = (s_state.running_game_custom_title || !s_state.running_game_entry) ?
std::string_view(s_state.running_game_title) :
s_state.running_game_entry->GetSaveTitle();
std::string card_path;
// Multi-disc game - use disc set name.
if (s_state.running_game_entry && s_state.running_game_entry->disc_set)
{
card_path = g_settings.GetGameMemoryCardPath(
Path::SanitizeFileName(s_state.running_game_entry->disc_set->GetSaveTitle()), slot);
}
// But prefer a disc-specific card if one already exists.
std::string disc_card_path = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(game_title), slot);
if (disc_card_path != card_path)
{
if (card_path.empty() || !g_settings.memory_card_use_playlist_title ||
FileSystem::FileExists(disc_card_path.c_str()))
{
if (g_settings.memory_card_use_playlist_title && !card_path.empty())
{
Host::AddIconOSDMessage(
fmt::format("DiscSpecificMC{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Using disc-specific memory card '{}' instead of per-game card."),
Path::GetFileName(disc_card_path)),
Host::OSD_INFO_DURATION);
}
card_path = std::move(disc_card_path);
}
}
Host::RemoveKeyedOSDMessage(std::move(message_key));
return MemoryCard::Open(card_path.c_str());
}
}
case MemoryCardType::PerGameFileTitle:
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(s_state.running_game_path));
const std::string_view file_title(Path::GetFileTitle(display_name));
if (file_title.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no path. Using shared card instead."),
slot + 1u));
return MemoryCard::Open(g_settings.GetSharedMemoryCardPath(slot));
}
else
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
return MemoryCard::Open(g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(file_title).c_str(), slot));
}
}
case MemoryCardType::Shared:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
return MemoryCard::Open(g_settings.GetSharedMemoryCardPath(slot));
}
case MemoryCardType::NonPersistent:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
return MemoryCard::Create();
}
case MemoryCardType::None:
default:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
return nullptr;
}
}
}
void System::UpdateMemoryCardTypes()
void System::UpdateMemoryCards()
{
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{
Pad::SetMemoryCard(i, nullptr);
const MemoryCardType type = g_settings.memory_card_types[i];
std::unique_ptr<MemoryCard> card = GetMemoryCardForSlot(i, type);
if (card)
if (type == MemoryCardType::None)
{
if (const std::string& path = card->GetPath(); !path.empty())
INFO_LOG("Memory Card Slot {}: {}", i + 1, path);
Pad::SetMemoryCard(i, std::move(card));
Pad::SetMemoryCard(i, {});
continue;
}
}
}
void System::ReloadMemoryCardsFromGameChange()
{
if (!g_settings.HasAnyPerGameMemoryCards())
return;
std::string path = GetMemoryCardPathForSlot(i, type);
Host::AddIconOSDMessage("ReloadMemoryCardsFromGameChange", ICON_PF_MEMORY_CARD,
TRANSLATE_STR("System", "Game changed, reloading memory cards."), Host::OSD_INFO_DURATION);
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{
const MemoryCardType type = g_settings.memory_card_types[i];
if (!Settings::IsPerGameMemoryCardType(type))
const MemoryCard* current_card = Pad::GetMemoryCard(i);
const bool path_changed = (!current_card || current_card->GetPath() != path);
INFO_LOG("Memory Card {}: {}{}", i + 1, path, path_changed ? "" : " [UNCHANGED]");
if (!path_changed)
continue;
Pad::SetMemoryCard(i, nullptr);
std::unique_ptr<MemoryCard> card = GetMemoryCardForSlot(i, type);
if (card)
if (current_card)
{
if (const std::string& path = card->GetPath(); !path.empty())
INFO_LOG("Memory Card Slot {}: {}", i + 1, path);
Pad::SetMemoryCard(i, std::move(card));
Host::AddIconOSDMessage(fmt::format("MemoryCardChange{}", i), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("OSDMessage", "Memory card in slot {} changed to '{}'."), i + 1,
Path::GetFileName(path)),
Host::OSD_INFO_DURATION);
}
std::unique_ptr<MemoryCard> card;
if (!path.empty())
card = MemoryCard::Open(std::move(path));
else
card = MemoryCard::Create();
Pad::SetMemoryCard(i, std::move(card));
}
}
@ -4232,7 +4101,8 @@ void System::UpdateRunningGame(const std::string& path, CDImage* image, bool boo
if (had_setting_overrides)
ApplySettings(true);
ReloadMemoryCardsFromGameChange();
if (g_settings.HasAnyPerGameMemoryCards())
UpdateMemoryCards();
}
}
@ -4710,7 +4580,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
g_settings.memory_card_paths != old_settings.memory_card_paths ||
(g_settings.memory_card_use_playlist_title != old_settings.memory_card_use_playlist_title))
{
UpdateMemoryCardTypes();
UpdateMemoryCards();
}
if (g_settings.rewind_enable != old_settings.rewind_enable ||
@ -5814,6 +5684,135 @@ std::string System::GetGameMemoryCardPath(std::string_view serial, std::string_v
return ret;
}
std::string System::GetMemoryCardPathForSlot(u32 slot, MemoryCardType type)
{
std::string ret;
// Disable memory cards when running PSFs/GPU dumps.
if ((!s_state.running_game_path.empty() && IsPsfPath(s_state.running_game_path.c_str())) || IsReplayingGPUDump())
return ret;
std::string message_key = fmt::format("MemoryCard{}SharedWarning", slot);
switch (type)
{
case MemoryCardType::PerGame:
{
if (s_state.running_game_serial.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no code. Using shared card instead."),
slot + 1u),
Host::OSD_INFO_DURATION);
ret = g_settings.GetSharedMemoryCardPath(slot);
}
else
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
ret = g_settings.GetGameMemoryCardPath(s_state.running_game_serial, slot);
}
}
break;
case MemoryCardType::PerGameTitle:
{
if (s_state.running_game_title.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no title. Using shared card instead."),
slot + 1u),
Host::OSD_INFO_DURATION);
ret = g_settings.GetSharedMemoryCardPath(slot);
}
else
{
const std::string_view game_title = (s_state.running_game_custom_title || !s_state.running_game_entry) ?
std::string_view(s_state.running_game_title) :
s_state.running_game_entry->GetSaveTitle();
std::string card_path;
// Multi-disc game - use disc set name.
if (s_state.running_game_entry && s_state.running_game_entry->disc_set)
{
card_path = g_settings.GetGameMemoryCardPath(
Path::SanitizeFileName(s_state.running_game_entry->disc_set->GetSaveTitle()), slot);
}
// But prefer a disc-specific card if one already exists.
std::string disc_card_path = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(game_title), slot);
if (disc_card_path != card_path)
{
if (card_path.empty() || !g_settings.memory_card_use_playlist_title ||
FileSystem::FileExists(disc_card_path.c_str()))
{
if (g_settings.memory_card_use_playlist_title && !card_path.empty())
{
Host::AddIconOSDMessage(
fmt::format("DiscSpecificMC{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Using disc-specific memory card '{}' instead of per-game card."),
Path::GetFileName(disc_card_path)),
Host::OSD_INFO_DURATION);
}
card_path = std::move(disc_card_path);
}
}
Host::RemoveKeyedOSDMessage(std::move(message_key));
ret = card_path;
}
}
break;
case MemoryCardType::PerGameFileTitle:
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(s_state.running_game_path));
const std::string_view file_title(Path::GetFileTitle(display_name));
if (file_title.empty())
{
Host::AddIconOSDMessage(
std::move(message_key), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("System", "Per-game memory card cannot be used for slot {} as the running "
"game has no path. Using shared card instead."),
slot + 1u));
ret = g_settings.GetSharedMemoryCardPath(slot);
}
else
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
ret = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(file_title).c_str(), slot);
}
}
break;
case MemoryCardType::Shared:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
ret = g_settings.GetSharedMemoryCardPath(slot);
}
break;
case MemoryCardType::NonPersistent:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
}
break;
case MemoryCardType::None:
default:
{
Host::RemoveKeyedOSDMessage(std::move(message_key));
}
break;
}
return ret;
}
std::string System::GetMostRecentResumeSaveStatePath()
{
FlushSaveStates();

@ -296,7 +296,7 @@ void SetVideoFrameRate(float frequency);
// Access controllers for simulating input.
Controller* GetController(u32 slot);
void UpdateMemoryCardTypes();
void UpdateMemoryCards();
bool HasMemoryCard(u32 slot);
bool IsSavingMemoryCards();

Loading…
Cancel
Save