System: Remove use of CDImage title metadata

This way memory card filenames are consistent regardless of the
image format.

Also make GetGameMemoryCardPath() and GetMemoryCardForSlot()
behave the same.
pull/3563/head
Stenzek 2 months ago
parent caa865628d
commit 6e4da72552
No known key found for this signature in database

@ -1182,12 +1182,6 @@ void Achievements::GameChanged(CDImage* image)
bool Achievements::IdentifyGame(CDImage* image) bool Achievements::IdentifyGame(CDImage* image)
{ {
if (s_state.game_path == (image ? std::string_view(image->GetPath()) : std::string_view()))
{
WARNING_LOG("Game path is unchanged.");
return false;
}
std::optional<GameHash> game_hash; std::optional<GameHash> game_hash;
if (image) if (image)
{ {

@ -358,10 +358,7 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
if (cdi->HasSubImages()) if (cdi->HasSubImages())
{ {
entry->type = EntryType::Playlist; entry->type = EntryType::Playlist;
entry->title = Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path));
std::string image_title(cdi->GetMetadata("title"));
if (!image_title.empty())
entry->title = std::move(image_title);
// get the size of all the subimages // get the size of all the subimages
const u32 subimage_count = cdi->GetSubImageCount(); const u32 subimage_count = cdi->GetSubImageCount();

@ -200,7 +200,7 @@ static bool SwitchDiscFromSet(s32 direction, bool show_osd_message);
static void UpdateControllers(); static void UpdateControllers();
static void ResetControllers(); static void ResetControllers();
static void UpdatePerGameMemoryCards(); static void ReloadMemoryCardsFromGameChange();
static std::unique_ptr<MemoryCard> GetMemoryCardForSlot(u32 slot, MemoryCardType type); static std::unique_ptr<MemoryCard> GetMemoryCardForSlot(u32 slot, MemoryCardType type);
static void UpdateMultitaps(); static void UpdateMultitaps();
@ -498,7 +498,10 @@ bool System::ProcessStartup(Error* error)
#ifdef __linux__ #ifdef __linux__
// Running DuckStation out of /usr/lib is not supported and makes no sense. // Running DuckStation out of /usr/lib is not supported and makes no sense.
if (std::memcmp(EmuFolders::AppRoot.data(), "/usr/""lib", 8) == 0) if (std::memcmp(EmuFolders::AppRoot.data(),
"/usr/"
"lib",
8) == 0)
return false; return false;
#endif #endif
@ -2984,8 +2987,7 @@ bool System::LoadStateFromBuffer(const SaveStateBuffer& buffer, Error* error, bo
} }
// ensure the correct card is loaded // ensure the correct card is loaded
if (g_settings.HasAnyPerGameMemoryCards()) ReloadMemoryCardsFromGameChange();
UpdatePerGameMemoryCards();
ClearMemorySaveStates(false, false); ClearMemorySaveStates(false, false);
@ -3812,17 +3814,12 @@ std::unique_ptr<MemoryCard> System::GetMemoryCardForSlot(u32 slot, MemoryCardTyp
else else
{ {
const std::string_view game_title = (s_state.running_game_custom_title || !s_state.running_game_entry) ? const std::string_view game_title = (s_state.running_game_custom_title || !s_state.running_game_entry) ?
s_state.running_game_title : std::string_view(s_state.running_game_title) :
s_state.running_game_entry->GetSaveTitle(); s_state.running_game_entry->GetSaveTitle();
std::string card_path; std::string card_path;
// Playlist - use title if different.
if (HasMediaSubImages() && s_state.running_game_entry && s_state.running_game_title != game_title)
{
card_path = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(s_state.running_game_title), slot);
}
// Multi-disc game - use disc set name. // Multi-disc game - use disc set name.
else if (s_state.running_game_entry && s_state.running_game_entry->disc_set) if (s_state.running_game_entry && s_state.running_game_entry->disc_set)
{ {
card_path = g_settings.GetGameMemoryCardPath( card_path = g_settings.GetGameMemoryCardPath(
Path::SanitizeFileName(s_state.running_game_entry->disc_set->GetSaveTitle()), slot); Path::SanitizeFileName(s_state.running_game_entry->disc_set->GetSaveTitle()), slot);
@ -3912,8 +3909,14 @@ void System::UpdateMemoryCardTypes()
} }
} }
void System::UpdatePerGameMemoryCards() void System::ReloadMemoryCardsFromGameChange()
{ {
if (!g_settings.HasAnyPerGameMemoryCards())
return;
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++) for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{ {
const MemoryCardType type = g_settings.memory_card_types[i]; const MemoryCardType type = g_settings.memory_card_types[i];
@ -4097,13 +4100,7 @@ bool System::InsertMedia(const char* path)
s_state.running_game_title, s_state.running_game_serial), s_state.running_game_title, s_state.running_game_serial),
Host::OSD_INFO_DURATION); Host::OSD_INFO_DURATION);
if (g_settings.HasAnyPerGameMemoryCards()) ReloadMemoryCardsFromGameChange();
{
Host::AddIconOSDMessage("ReloadMemoryCardsFromGameChange", ICON_PF_MEMORY_CARD,
TRANSLATE_STR("System", "Game changed, reloading memory cards."), Host::OSD_INFO_DURATION);
UpdatePerGameMemoryCards();
}
return true; return true;
} }
@ -4115,9 +4112,6 @@ void System::RemoveMedia()
void System::UpdateRunningGame(const std::string& path, CDImage* image, bool booting) void System::UpdateRunningGame(const std::string& path, CDImage* image, bool booting)
{ {
if (!booting && s_state.running_game_path == path)
return;
const std::string prev_serial = std::move(s_state.running_game_serial); const std::string prev_serial = std::move(s_state.running_game_serial);
s_state.running_game_path.clear(); s_state.running_game_path.clear();
@ -4195,16 +4189,6 @@ void System::UpdateRunningGame(const std::string& path, CDImage* image, bool boo
if (s_state.running_game_title.empty() && !CDImage::IsDeviceName(path.c_str())) if (s_state.running_game_title.empty() && !CDImage::IsDeviceName(path.c_str()))
s_state.running_game_title = Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path)); s_state.running_game_title = Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path));
} }
if (image->HasSubImages())
{
std::string image_title = image->GetMetadata("title");
if (!image_title.empty())
{
s_state.running_game_title = std::move(image_title);
s_state.running_game_custom_title = false;
}
}
} }
else else
{ {
@ -4296,29 +4280,13 @@ u32 System::GetMediaSubImageIndex()
return cdi ? cdi->GetCurrentSubImage() : 0; return cdi ? cdi->GetCurrentSubImage() : 0;
} }
u32 System::GetMediaSubImageIndexForTitle(std::string_view title)
{
const CDImage* cdi = CDROM::GetMedia();
if (!cdi)
return 0;
const u32 count = cdi->GetSubImageCount();
for (u32 i = 0; i < count; i++)
{
if (title == cdi->GetSubImageMetadata(i, "title"))
return i;
}
return std::numeric_limits<u32>::max();
}
std::string System::GetMediaSubImageTitle(u32 index) std::string System::GetMediaSubImageTitle(u32 index)
{ {
const CDImage* cdi = CDROM::GetMedia(); const CDImage* cdi = CDROM::GetMedia();
if (!cdi) if (!cdi)
return {}; return {};
return cdi->GetSubImageMetadata(index, "title"); return cdi->GetSubImageTitle(index);
} }
bool System::SwitchMediaSubImage(u32 index) bool System::SwitchMediaSubImage(u32 index)
@ -4338,9 +4306,10 @@ bool System::SwitchMediaSubImage(u32 index)
{ {
const DiscRegion region = const DiscRegion region =
GameList::GetCustomRegionForPath(image->GetPath()).value_or(GetRegionForImage(image.get())); GameList::GetCustomRegionForPath(image->GetPath()).value_or(GetRegionForImage(image.get()));
subimage_title = image->GetSubImageMetadata(index, "title"); subimage_title = image->GetSubImageTitle(index);
title = image->GetMetadata("title"); title = FileSystem::GetDisplayNameFromPath(image->GetPath());
UpdateRunningGame(image->GetPath(), image.get(), false); UpdateRunningGame(image->GetPath(), image.get(), false);
ReloadMemoryCardsFromGameChange();
okay = CDROM::InsertMedia(image, region, s_state.running_game_serial, s_state.running_game_title, &error); okay = CDROM::InsertMedia(image, region, s_state.running_game_serial, s_state.running_game_title, &error);
} }
if (!okay) if (!okay)
@ -5781,22 +5750,24 @@ std::string System::GetGameMemoryCardPath(std::string_view serial, std::string_v
case MemoryCardType::PerGameTitle: case MemoryCardType::PerGameTitle:
{ {
const std::string custom_title = GameList::GetCustomTitleForPath(path);
const GameDatabase::Entry* entry = GameDatabase::GetEntryForSerial(serial); const GameDatabase::Entry* entry = GameDatabase::GetEntryForSerial(serial);
if (entry) const std::string_view game_title =
{ (!custom_title.empty() || !entry) ? std::string_view(custom_title) : entry->GetSaveTitle();
ret = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(entry->GetSaveTitle()), slot);
// Multi-disc game - use disc set name.
if (entry && entry->disc_set)
ret = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(entry->disc_set->GetSaveTitle()), slot);
// Use disc set name if there isn't a per-disc card present. // 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 != ret)
{
const bool global_use_playlist_title = Host::GetBaseBoolSettingValue(section, "UsePlaylistTitle", true); const bool global_use_playlist_title = Host::GetBaseBoolSettingValue(section, "UsePlaylistTitle", true);
const bool use_playlist_title = const bool use_playlist_title =
ini ? ini->GetBoolValue(section, "UsePlaylistTitle", global_use_playlist_title) : global_use_playlist_title; ini ? ini->GetBoolValue(section, "UsePlaylistTitle", global_use_playlist_title) : global_use_playlist_title;
if (entry->disc_set && use_playlist_title && !FileSystem::FileExists(ret.c_str())) if (ret.empty() || !use_playlist_title || FileSystem::FileExists(disc_card_path.c_str()))
ret = g_settings.GetGameMemoryCardPath(Path::SanitizeFileName(entry->disc_set->GetSaveTitle()), slot); ret = std::move(disc_card_path);
}
else
{
ret = g_settings.GetGameMemoryCardPath(
Path::SanitizeFileName(Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path))), slot);
} }
} }
break; break;

@ -323,9 +323,6 @@ u32 GetMediaSubImageCount();
/// Returns the current image from the media/disc playlist. /// Returns the current image from the media/disc playlist.
u32 GetMediaSubImageIndex(); u32 GetMediaSubImageIndex();
/// Returns the index of the specified path in the playlist, or UINT32_MAX if it does not exist.
u32 GetMediaSubImageIndexForTitle(std::string_view title);
/// Returns the path to the specified playlist index. /// Returns the path to the specified playlist index.
std::string GetMediaSubImageTitle(u32 index); std::string GetMediaSubImageTitle(u32 index);

@ -1287,6 +1287,7 @@ void MainWindow::onChangeDiscMenuAboutToShow()
if (!s_system_valid) if (!s_system_valid)
return; return;
// NOTE: This is terrible and a race condition. But nobody should be using m3u files anyway.
if (System::HasMediaSubImages()) if (System::HasMediaSubImages())
{ {
const u32 count = System::GetMediaSubImageCount(); const u32 count = System::GetMediaSubImageCount();

@ -304,18 +304,6 @@ bool CDImage::HasSubchannelData() const
return false; return false;
} }
std::string CDImage::GetMetadata(std::string_view type) const
{
std::string result;
if (type == "title")
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(m_filename));
result = Path::StripExtension(display_name);
}
return result;
}
bool CDImage::HasSubImages() const bool CDImage::HasSubImages() const
{ {
return false; return false;
@ -336,7 +324,7 @@ bool CDImage::SwitchSubImage(u32 index, Error* error)
return false; return false;
} }
std::string CDImage::GetSubImageMetadata(u32 index, std::string_view type) const std::string CDImage::GetSubImageTitle(u32 index) const
{ {
return {}; return {};
} }

@ -290,9 +290,6 @@ public:
// Reads a single sector from an index. // Reads a single sector from an index.
virtual bool ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) = 0; virtual bool ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) = 0;
// Retrieve image metadata.
virtual std::string GetMetadata(std::string_view type) const;
// Returns true if this image type has sub-images (e.g. m3u). // Returns true if this image type has sub-images (e.g. m3u).
virtual bool HasSubImages() const; virtual bool HasSubImages() const;
@ -306,7 +303,7 @@ public:
virtual bool SwitchSubImage(u32 index, Error* error); virtual bool SwitchSubImage(u32 index, Error* error);
// Retrieve sub-image metadata. // Retrieve sub-image metadata.
virtual std::string GetSubImageMetadata(u32 index, std::string_view type) const; virtual std::string GetSubImageTitle(u32 index) const;
// Returns true if the source supports precaching, which may be more optimal than an in-memory copy. // Returns true if the source supports precaching, which may be more optimal than an in-memory copy.
virtual PrecacheResult Precache(ProgressCallback* progress = ProgressCallback::NullProgressCallback); virtual PrecacheResult Precache(ProgressCallback* progress = ProgressCallback::NullProgressCallback);

@ -33,7 +33,7 @@ public:
bool HasSubImages() const override; bool HasSubImages() const override;
u32 GetSubImageCount() const override; u32 GetSubImageCount() const override;
u32 GetCurrentSubImage() const override; u32 GetCurrentSubImage() const override;
std::string GetSubImageMetadata(u32 index, std::string_view type) const override; std::string GetSubImageTitle(u32 index) const override;
bool SwitchSubImage(u32 index, Error* error) override; bool SwitchSubImage(u32 index, Error* error) override;
protected: protected:
@ -159,17 +159,13 @@ bool CDImageM3u::SwitchSubImage(u32 index, Error* error)
return true; return true;
} }
std::string CDImageM3u::GetSubImageMetadata(u32 index, std::string_view type) const std::string CDImageM3u::GetSubImageTitle(u32 index) const
{ {
if (index >= m_entries.size()) std::string ret;
return {}; if (index < m_entries.size())
ret = m_entries[index].title;
if (type == "title")
return m_entries[index].title;
else if (type == "file_title")
return std::string(Path::GetFileTitle(m_entries[index].filename));
return CDImage::GetSubImageMetadata(index, type); return ret;
} }
bool CDImageM3u::ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) bool CDImageM3u::ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index)

@ -139,8 +139,7 @@ public:
u32 GetSubImageCount() const override; u32 GetSubImageCount() const override;
u32 GetCurrentSubImage() const override; u32 GetCurrentSubImage() const override;
bool SwitchSubImage(u32 index, Error* error) override; bool SwitchSubImage(u32 index, Error* error) override;
std::string GetMetadata(std::string_view type) const override; std::string GetSubImageTitle(u32 index) const override;
std::string GetSubImageMetadata(u32 index, std::string_view type) const override;
protected: protected:
bool ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) override; bool ReadSectorFromIndex(void* buffer, const Index& index, LBA lba_in_index) override;
@ -336,7 +335,8 @@ bool CDImagePBP::LoadSFOTable(Error* error)
} }
else else
{ {
Error::SetStringFmt(error, "Unhandled SFO data type 0x{:04X} found in SFO table for entry {}", m_sfo_index_table[i].data_type, i); Error::SetStringFmt(error, "Unhandled SFO data type 0x{:04X} found in SFO table for entry {}",
m_sfo_index_table[i].data_type, i);
return false; return false;
} }
} }
@ -871,18 +871,6 @@ bool CDImagePBP::HasSubImages() const
return m_disc_offsets.size() > 1; return m_disc_offsets.size() > 1;
} }
std::string CDImagePBP::GetMetadata(std::string_view type) const
{
if (type == "title")
{
const std::string* title = LookupStringSFOTableEntry("TITLE", m_sfo_table);
if (title && !title->empty())
return *title;
}
return CDImage::GetMetadata(type);
}
u32 CDImagePBP::GetSubImageCount() const u32 CDImagePBP::GetSubImageCount() const
{ {
return static_cast<u32>(m_disc_offsets.size()); return static_cast<u32>(m_disc_offsets.size());
@ -909,16 +897,15 @@ bool CDImagePBP::SwitchSubImage(u32 index, Error* error)
return true; return true;
} }
std::string CDImagePBP::GetSubImageMetadata(u32 index, std::string_view type) const std::string CDImagePBP::GetSubImageTitle(u32 index) const
{ {
if (type == "title") std::string ret;
{
const std::string* title = LookupStringSFOTableEntry("TITLE", m_sfo_table); const std::string* title = LookupStringSFOTableEntry("TITLE", m_sfo_table);
if (title && !title->empty()) if (title && !title->empty())
return fmt::format("{} (Disc {})", *title, index + 1); ret = fmt::format("{} (Disc {})", *title, index + 1);
}
return CDImage::GetSubImageMetadata(index, type); return ret;
} }
s64 CDImagePBP::GetSizeOnDisk() const s64 CDImagePBP::GetSizeOnDisk() const

@ -35,8 +35,7 @@ public:
bool HasSubchannelData() const override; bool HasSubchannelData() const override;
s64 GetSizeOnDisk() const override; s64 GetSizeOnDisk() const override;
std::string GetMetadata(std::string_view type) const override; std::string GetSubImageTitle(u32 index) const override;
std::string GetSubImageMetadata(u32 index, std::string_view type) const override;
PrecacheResult Precache(ProgressCallback* progress = ProgressCallback::NullProgressCallback) override; PrecacheResult Precache(ProgressCallback* progress = ProgressCallback::NullProgressCallback) override;
@ -420,19 +419,10 @@ bool CDImagePPF::HasSubchannelData() const
return m_parent_image->HasSubchannelData(); return m_parent_image->HasSubchannelData();
} }
std::string CDImagePPF::GetMetadata(std::string_view type) const std::string CDImagePPF::GetSubImageTitle(u32 index) const
{
return m_parent_image->GetMetadata(type);
}
std::string CDImagePPF::GetSubImageMetadata(u32 index, std::string_view type) const
{ {
// We only support a single sub-image for patched games. // We only support a single sub-image for patched games.
std::string ret; return (index == 0) ? m_parent_image->GetSubImageTitle(index) : std::string();
if (index == 0)
ret = m_parent_image->GetSubImageMetadata(index, type);
return ret;
} }
CDImage::PrecacheResult CDImagePPF::Precache(ProgressCallback* progress /*= ProgressCallback::NullProgressCallback*/) CDImage::PrecacheResult CDImagePPF::Precache(ProgressCallback* progress /*= ProgressCallback::NullProgressCallback*/)

Loading…
Cancel
Save