diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 619c7f0d6..0e6a84e14 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -908,11 +908,13 @@ const char* Settings::GetControllerTypeDisplayName(ControllerType type) return s_controller_display_names[static_cast(type)]; } -static std::array s_memory_card_type_names = {{"None", "Shared", "PerGame", "PerGameTitle"}}; -static std::array s_memory_card_type_display_names = { +static std::array s_memory_card_type_names = { + {"None", "Shared", "PerGame", "PerGameTitle", "PerGameFileTitle"}}; +static std::array s_memory_card_type_display_names = { {TRANSLATABLE("MemoryCardType", "No Memory Card"), TRANSLATABLE("MemoryCardType", "Shared Between All Games"), TRANSLATABLE("MemoryCardType", "Separate Card Per Game (Game Code)"), - TRANSLATABLE("MemoryCardType", "Separate Card Per Game (Game Title)")}}; + TRANSLATABLE("MemoryCardType", "Separate Card Per Game (Game Title)"), + TRANSLATABLE("MemoryCardType", "Separate Card Per Game (File Title)")}}; std::optional Settings::ParseMemoryCardTypeName(const char* str) { diff --git a/src/core/system.cpp b/src/core/system.cpp index 12485712d..e29a0290f 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1821,6 +1821,28 @@ void UpdateMemoryCards() } break; + case MemoryCardType::PerGameFileTitle: + { + const std::string display_name(FileSystem::GetDisplayNameFromPath(s_running_game_path)); + const std::string_view file_title(FileSystem::GetFileTitleFromPath(display_name)); + if (file_title.empty()) + { + g_host_interface->AddFormattedOSDMessage( + 5.0f, + g_host_interface->TranslateString("System", + "Per-game memory card cannot be used for slot %u as the running " + "game has no path. Using shared card instead."), + i + 1u); + card = MemoryCard::Open(g_host_interface->GetSharedMemoryCardPath(i)); + } + else + { + card = MemoryCard::Open( + g_host_interface->GetGameMemoryCardPath(MemoryCard::SanitizeGameTitleForFileName(file_title).c_str(), i)); + } + } + break; + case MemoryCardType::Shared: { if (g_settings.memory_card_paths[i].empty()) diff --git a/src/core/types.h b/src/core/types.h index 86709dbf1..9b5ca022b 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -134,6 +134,7 @@ enum class MemoryCardType Shared, PerGame, PerGameTitle, + PerGameFileTitle, Count }; diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index d8226d6e5..1786bf075 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -1050,6 +1050,13 @@ void QtHostInterface::populateGameListContextMenu(const GameListEntry* entry, QW paths[i] = QString::fromStdString( GetGameMemoryCardPath(MemoryCard::SanitizeGameTitleForFileName(entry->title).c_str(), i)); break; + case MemoryCardType::PerGameFileTitle: + { + const std::string display_name(FileSystem::GetDisplayNameFromPath(entry->path)); + paths[i] = QString::fromStdString(GetGameMemoryCardPath( + MemoryCard::SanitizeGameTitleForFileName(FileSystem::GetFileTitleFromPath(display_name)).c_str(), i)); + } + break; default: break; }