MemoryCard: Show game icon when saving

This commit is contained in:
Stenzek
2025-12-01 02:05:46 +10:00
parent 7970287d69
commit 8e3a65c152
8 changed files with 44 additions and 18 deletions

View File

@@ -2027,28 +2027,33 @@ void GameList::ReloadMemcardTimestampCache()
}
std::string GameList::GetGameIconPath(const GameList::Entry* entry)
{
return GetGameIconPath(entry->title, entry->serial, entry->path, entry->achievements_game_id);
}
std::string GameList::GetGameIconPath(std::string_view custom_title, std::string_view serial, std::string_view path,
u32 achievements_game_id)
{
std::string ret;
std::string fallback_path;
if (entry->achievements_game_id != 0)
if (achievements_game_id != 0)
{
fallback_path = GetAchievementGameBadgePath(entry->achievements_game_id);
fallback_path = GetAchievementGameBadgePath(achievements_game_id);
if (!fallback_path.empty() && PreferAchievementGameBadgesForIcons())
return (ret = std::move(fallback_path));
}
if (entry->serial.empty())
if (serial.empty())
return (ret = std::move(fallback_path));
// might exist already, or the user used a custom icon
ret = Path::Combine(EmuFolders::GameIcons, TinyString::from_format("{}.png", entry->serial));
ret = Path::Combine(EmuFolders::GameIcons, TinyString::from_format("{}.png", serial));
if (FileSystem::FileExists(ret.c_str()))
return ret;
MemoryCardType type;
std::string memcard_path =
System::GetGameMemoryCardPath(entry->title, entry->has_custom_title, entry->serial, entry->path, 0, &type);
std::string memcard_path = System::GetGameMemoryCardPath(custom_title, serial, path, 0, &type);
FILESYSTEM_STAT_DATA memcard_sd;
if (memcard_path.empty() || type == MemoryCardType::Shared ||
!FileSystem::StatFile(memcard_path.c_str(), &memcard_sd))
@@ -2058,8 +2063,8 @@ std::string GameList::GetGameIconPath(const GameList::Entry* entry)
const s64 timestamp = memcard_sd.ModificationTime;
TinyString index_serial;
index_serial.assign(entry->serial.substr(
0, std::min<size_t>(entry->serial.length(), MemcardTimestampCacheEntry::MAX_SERIAL_LENGTH - 1)));
index_serial.assign(
serial.substr(0, std::min<size_t>(serial.length(), MemcardTimestampCacheEntry::MAX_SERIAL_LENGTH - 1)));
MemcardTimestampCacheEntry* cache_entry = nullptr;
for (MemcardTimestampCacheEntry& it : s_state.memcard_timestamp_cache_entries)

View File

@@ -171,6 +171,8 @@ std::optional<DiscRegion> GetCustomRegionForPath(const std::string_view path);
/// The purpose of this cache is to stop us trying to constantly extract memory card icons, when we know a game
/// doesn't have any saves yet. It caches the serial:memcard_timestamp pair, and only tries extraction when the
/// timestamp of the memory card has changed.
std::string GetGameIconPath(std::string_view title, std::string_view serial, std::string_view path,
u32 achievements_game_id);
std::string GetGameIconPath(const GameList::Entry* entry);
void ReloadMemcardTimestampCache();

View File

@@ -380,8 +380,12 @@ bool MemoryCard::SaveIfChanged(bool display_osd_message)
if (display_osd_message)
{
std::string icon_path = System::GetGameIconPath();
if (icon_path.empty())
icon_path = ICON_PF_MEMORY_CARD;
Host::AddIconOSDMessage(
OSDMessageType::Quick, GetOSDMessageKey(m_index), ICON_PF_MEMORY_CARD,
OSDMessageType::Quick, GetOSDMessageKey(m_index), std::move(icon_path),
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card Slot {}"), m_index + 1),
fmt::format(TRANSLATE_FS("MemoryCard", "Saved card to '{}'."), Path::GetFileName(display_name)));
}

View File

@@ -806,6 +806,14 @@ System::BootMode System::GetBootMode()
return s_state.boot_mode;
}
std::string System::GetGameIconPath()
{
return GameList::GetGameIconPath((s_state.running_game_custom_title || !s_state.running_game_entry) ?
std::string_view(s_state.running_game_title) :
std::string_view(),
s_state.running_game_serial, s_state.running_game_path, Achievements::GetGameID());
}
bool System::IsUsingKnownPS1BIOS()
{
return (s_state.bios_image_info && s_state.bios_image_info->fastboot_patch == BIOS::ImageInfo::FastBootPatch::Type1);
@@ -5761,8 +5769,8 @@ void System::DeleteSaveStates(std::string_view serial, bool resume)
}
}
std::string System::GetGameMemoryCardPath(std::string_view title, bool is_custom_title, std::string_view serial,
std::string_view path, u32 slot, MemoryCardType* out_type /* = nullptr */)
std::string System::GetGameMemoryCardPath(std::string_view custom_title, std::string_view serial, std::string_view path,
u32 slot, MemoryCardType* out_type /* = nullptr */)
{
const char* section = "MemoryCards";
const TinyString type_key = TinyString::from_format("Card{}Type", slot + 1);
@@ -5822,7 +5830,7 @@ std::string System::GetGameMemoryCardPath(std::string_view title, bool is_custom
case MemoryCardType::PerGameTitle:
{
const GameDatabase::Entry* entry = GameDatabase::GetEntryForSerial(serial);
const std::string_view game_title = (is_custom_title || !entry) ? title : entry->GetSaveTitle();
const std::string_view game_title = (!custom_title.empty() || !entry) ? custom_title : entry->GetSaveTitle();
// Multi-disc game - use disc set name.
if (entry && entry->disc_set)

View File

@@ -237,6 +237,9 @@ bool IsRunningUnknownGame();
bool IsUsingKnownPS1BIOS();
BootMode GetBootMode();
/// Returns a path to the game icon, if any.
std::string GetGameIconPath();
/// Returns the time elapsed in the current play session.
u64 GetSessionPlayedTime();
@@ -404,8 +407,8 @@ std::optional<ExtendedSaveStateInfo> GetExtendedSaveStateInfo(const char* path);
void DeleteSaveStates(std::string_view serial, bool resume);
/// Returns the path to the memory card for the specified game, considering game settings.
std::string GetGameMemoryCardPath(std::string_view title, bool is_custom_title, std::string_view serial,
std::string_view path, u32 slot, MemoryCardType* out_type = nullptr);
std::string GetGameMemoryCardPath(std::string_view save_title, std::string_view serial, std::string_view path, u32 slot,
MemoryCardType* out_type = nullptr);
/// Returns intended output volume considering fast forwarding.
u8 GetAudioOutputVolume();

View File

@@ -910,10 +910,7 @@ void MainWindow::populateGameListContextMenu(const GameList::Entry* entry, QWidg
QString paths[2];
for (u32 i = 0; i < 2; i++)
{
paths[i] = QString::fromStdString(
System::GetGameMemoryCardPath(entry->title, entry->has_custom_title, entry->serial, entry->path, i));
}
paths[i] = QString::fromStdString(System::GetGameMemoryCardPath(entry->title, entry->serial, entry->path, i));
g_main_window->openMemoryCardEditor(paths[0], paths[1]);
});

View File

@@ -1172,6 +1172,12 @@ void Host::AddIconOSDMessage(OSDMessageType type, std::string key, const char* i
ImGuiManager::AddOSDMessage(type, std::move(key), std::string(icon), std::move(title), std::move(message));
}
void Host::AddIconOSDMessage(OSDMessageType type, std::string key, std::string icon, std::string title,
std::string message)
{
ImGuiManager::AddOSDMessage(type, std::move(key), std::move(icon), std::move(title), std::move(message));
}
void Host::RemoveKeyedOSDMessage(std::string key)
{
ImGuiManager::RemoveKeyedOSDMessage(std::move(key));

View File

@@ -238,6 +238,7 @@ void AddOSDMessage(OSDMessageType type, std::string message);
void AddKeyedOSDMessage(OSDMessageType type, std::string key, std::string message);
void AddIconOSDMessage(OSDMessageType type, std::string key, const char* icon, std::string message);
void AddIconOSDMessage(OSDMessageType type, std::string key, const char* icon, std::string title, std::string message);
void AddIconOSDMessage(OSDMessageType type, std::string key, std::string icon, std::string title, std::string message);
void RemoveKeyedOSDMessage(std::string key);
void ClearOSDMessages();