diff --git a/pcsx2-qt/Settings/GameSummaryWidget.cpp b/pcsx2-qt/Settings/GameSummaryWidget.cpp
index 3e4239984b..9bbbf8c337 100644
--- a/pcsx2-qt/Settings/GameSummaryWidget.cpp
+++ b/pcsx2-qt/Settings/GameSummaryWidget.cpp
@@ -63,6 +63,11 @@ GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialo
connect(m_ui.inputProfile, &QComboBox::currentIndexChanged, this, &GameSummaryWidget::onInputProfileChanged);
connect(m_ui.verify, &QAbstractButton::clicked, this, &GameSummaryWidget::onVerifyClicked);
connect(m_ui.searchHash, &QAbstractButton::clicked, this, &GameSummaryWidget::onSearchHashClicked);
+
+ bool has_custom_title = false, has_custom_region = false;
+ GameList::CheckCustomAttributesForPath(m_entry_path, has_custom_title, has_custom_region);
+ m_ui.restoreTitle->setEnabled(has_custom_title);
+ m_ui.restoreRegion->setEnabled(has_custom_region);
}
GameSummaryWidget::~GameSummaryWidget() = default;
@@ -88,6 +93,24 @@ void GameSummaryWidget::populateDetails(const GameList::Entry* entry)
m_ui.inputProfile->setCurrentIndex(m_ui.inputProfile->findText(QString::fromStdString(profile.value())));
else
m_ui.inputProfile->setCurrentIndex(0);
+
+ connect(m_ui.title, &QLineEdit::editingFinished, this, [this]() {
+ if (m_ui.title->isModified())
+ {
+ setCustomTitle(m_ui.title->text().toStdString());
+ m_ui.title->setModified(false);
+ }
+ });
+ connect(m_ui.restoreTitle, &QAbstractButton::clicked, this, [this]() {
+ setCustomTitle("");
+ });
+
+ connect(m_ui.region, &QComboBox::currentIndexChanged, this, [this](int index) {
+ setCustomRegion(index);
+ });
+ connect(m_ui.restoreRegion, &QAbstractButton::clicked, this, [this]() {
+ setCustomRegion(-1);
+ });
}
void GameSummaryWidget::populateDiscPath(const GameList::Entry* entry)
@@ -129,12 +152,7 @@ void GameSummaryWidget::onDiscPathChanged(const QString& value)
// force rescan of elf to update the serial
g_main_window->rescanFile(m_entry_path);
-
- // and re-fill our details (mainly the serial)
- auto lock = GameList::GetLock();
- const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
- if (entry)
- populateDetails(entry);
+ repopulateCurrentDetails();
}
void GameSummaryWidget::onDiscPathBrowseClicked()
@@ -352,4 +370,31 @@ void GameSummaryWidget::setVerifyResult(QString error)
m_ui.verifyResult->setPlainText(error);
m_ui.verifyResult->setVisible(true);
m_ui.searchHash->setVisible(true);
-}
\ No newline at end of file
+}
+
+void GameSummaryWidget::repopulateCurrentDetails()
+{
+ auto lock = GameList::GetLock();
+ const GameList::Entry* entry = GameList::GetEntryForPath(m_entry_path.c_str());
+ if (entry)
+ {
+ populateDetails(entry);
+ m_dialog->setWindowTitle(QString::fromStdString(entry->title));
+ }
+}
+
+void GameSummaryWidget::setCustomTitle(const std::string& text)
+{
+ m_ui.restoreTitle->setEnabled(!text.empty());
+
+ GameList::SaveCustomTitleForPath(m_entry_path, text);
+ repopulateCurrentDetails();
+}
+
+void GameSummaryWidget::setCustomRegion(int region)
+{
+ m_ui.restoreRegion->setEnabled(region >= 0);
+
+ GameList::SaveCustomRegionForPath(m_entry_path, region);
+ repopulateCurrentDetails();
+}
diff --git a/pcsx2-qt/Settings/GameSummaryWidget.h b/pcsx2-qt/Settings/GameSummaryWidget.h
index fba321a902..75f1e78788 100644
--- a/pcsx2-qt/Settings/GameSummaryWidget.h
+++ b/pcsx2-qt/Settings/GameSummaryWidget.h
@@ -47,6 +47,10 @@ private:
void populateDiscPath(const GameList::Entry* entry);
void populateTrackList(const GameList::Entry* entry);
void setVerifyResult(QString error);
+ void repopulateCurrentDetails();
+
+ void setCustomTitle(const std::string& text);
+ void setCustomRegion(int region);
Ui::GameSummaryWidget m_ui;
SettingsDialog* m_dialog;
diff --git a/pcsx2-qt/Settings/GameSummaryWidget.ui b/pcsx2-qt/Settings/GameSummaryWidget.ui
index 307e516a71..9d00f7bd17 100644
--- a/pcsx2-qt/Settings/GameSummaryWidget.ui
+++ b/pcsx2-qt/Settings/GameSummaryWidget.ui
@@ -34,11 +34,25 @@
-
-
-
- true
-
-
+
+
-
+
+
+ Clear the line to restore the original title...
+
+
+
+ -
+
+
+ false
+
+
+ Restore
+
+
+
+
-
@@ -140,170 +154,178 @@
-
-
-
- false
-
-
-
- 0
- 0
-
-
-
- true
-
-
-
-
- NTSC-B (Brazil)
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
-
+
+ NTSC-B (Brazil)
+
+
+ -
+
+ NTSC-C (China)
+
+
+ -
+
+ NTSC-HK (Hong Kong)
+
+
+ -
+
+ NTSC-J (Japan)
+
+
+ -
+
+ NTSC-K (Korea)
+
+
+ -
+
+ NTSC-T (Taiwan)
+
+
+ -
+
+ NTSC-U (US)
+
+
+ -
+
+ Other
+
+
+ -
+
+ PAL-A (Australia)
+
+
+ -
+
+ PAL-AF (South Africa)
+
+
+ -
+
+ PAL-AU (Austria)
+
+
+ -
+
+ PAL-BE (Belgium)
+
+
+ -
+
+ PAL-E (Europe/Australia)
+
+
+ -
+
+ PAL-F (France)
+
+
+ -
+
+ PAL-FI (Finland)
+
+
+ -
+
+ PAL-G (Germany)
+
+
+ -
+
+ PAL-GR (Greece)
+
+
+ -
+
+ PAL-I (Italy)
+
+
+ -
+
+ PAL-IN (India)
+
+
+ -
+
+ PAL-M (Europe/Australia)
+
+
+ -
+
+ PAL-NL (Netherlands)
+
+
+ -
+
+ PAL-NO (Norway)
+
+
+ -
+
+ PAL-P (Portugal)
+
+
+ -
+
+ PAL-PL (Poland)
+
+
+ -
+
+ PAL-R (Russia)
+
+
+ -
+
+ PAL-S (Spain)
+
+
+ -
+
+ PAL-SC (Scandinavia)
+
+
+ -
+
+ PAL-SW (Sweden)
+
+
+ -
+
+ PAL-SWI (Switzerland)
+
+
+ -
+
+ PAL-UK (United Kingdom)
+
+
+
+
+ -
+
+
+ false
+
+
+ Restore
+
+
- -
-
- NTSC-C (China)
-
-
- -
-
- NTSC-HK (Hong Kong)
-
-
- -
-
- NTSC-J (Japan)
-
-
- -
-
- NTSC-K (Korea)
-
-
- -
-
- NTSC-T (Taiwan)
-
-
- -
-
- NTSC-U (US)
-
-
- -
-
- Other
-
-
- -
-
- PAL-A (Australia)
-
-
- -
-
- PAL-AF (South Africa)
-
-
- -
-
- PAL-AU (Austria)
-
-
- -
-
- PAL-BE (Belgium)
-
-
- -
-
- PAL-E (Europe/Australia)
-
-
- -
-
- PAL-F (France)
-
-
- -
-
- PAL-FI (Finland)
-
-
- -
-
- PAL-G (Germany)
-
-
- -
-
- PAL-GR (Greece)
-
-
- -
-
- PAL-I (Italy)
-
-
- -
-
- PAL-IN (India)
-
-
- -
-
- PAL-M (Europe/Australia)
-
-
- -
-
- PAL-NL (Netherlands)
-
-
- -
-
- PAL-NO (Norway)
-
-
- -
-
- PAL-P (Portugal)
-
-
- -
-
- PAL-PL (Poland)
-
-
- -
-
- PAL-R (Russia)
-
-
- -
-
- PAL-S (Spain)
-
-
- -
-
- PAL-SC (Scandinavia)
-
-
- -
-
- PAL-SW (Sweden)
-
-
- -
-
- PAL-SWI (Switzerland)
-
-
- -
-
- PAL-UK (United Kingdom)
-
-
-
+
-
@@ -488,22 +510,22 @@
60
-
- true
-
false
+
+ true
+
-
-
- Search on Redump.org...
-
false
+
+ Search on Redump.org...
+
diff --git a/pcsx2-qt/Settings/SettingsDialog.cpp b/pcsx2-qt/Settings/SettingsDialog.cpp
index 7277937fc3..1ef4ae1475 100644
--- a/pcsx2-qt/Settings/SettingsDialog.cpp
+++ b/pcsx2-qt/Settings/SettingsDialog.cpp
@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see .
*/
-
+
#include "PrecompiledHeader.h"
#include "MainWindow.h"
@@ -59,11 +59,12 @@ SettingsDialog::SettingsDialog(QWidget* parent)
}
SettingsDialog::SettingsDialog(QWidget* parent, std::unique_ptr sif, const GameList::Entry* game,
- std::string serial, u32 disc_crc)
+ std::string serial, u32 disc_crc, QString filename)
: QDialog(parent)
, m_sif(std::move(sif))
, m_serial(std::move(serial))
, m_disc_crc(disc_crc)
+ , m_filename(std::move(filename))
{
setupUi(game);
@@ -80,9 +81,9 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
if (isPerGameSettings())
{
QString summary = tr("Summary
This page shows details about the selected game. Changing the Input "
- "Profile will set the controller binding scheme for this game to whichever profile is chosen, instead "
- "of the default (Shared) configuration. The track list and dump verification can be used to determine "
- "if your disc image matches a known good dump. If it does not match, the game may be broken.");
+ "Profile will set the controller binding scheme for this game to whichever profile is chosen, instead "
+ "of the default (Shared) configuration. The track list and dump verification can be used to determine "
+ "if your disc image matches a known good dump. If it does not match, the game may be broken.");
if (game)
{
addWidget(new GameSummaryWidget(game, this, m_ui.settingsContainer), tr("Summary"),
@@ -153,7 +154,7 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
addWidget(m_memory_card_settings = new MemoryCardSettingsWidget(this, m_ui.settingsContainer), tr("Memory Cards"),
QStringLiteral("memcard-line"),
tr("Memory Card Settings
Create and configure Memory Cards here.
Mouse over an option for "
- "additional information."));
+ "additional information."));
addWidget(m_dev9_settings = new DEV9SettingsWidget(this, m_ui.settingsContainer), tr("Network & HDD"), QStringLiteral("global-line"),
tr("Network & HDD Settings
These options control the network connectivity and internal HDD storage of the "
@@ -330,6 +331,18 @@ bool SettingsDialog::eventFilter(QObject* object, QEvent* event)
return QDialog::eventFilter(object, event);
}
+void SettingsDialog::setWindowTitle(const QString& title)
+{
+ if (m_filename.isEmpty())
+ {
+ QDialog::setWindowTitle(title);
+ }
+ else
+ {
+ QDialog::setWindowTitle(QStringLiteral("%1 [%2]").arg(title, m_filename));
+ }
+}
+
bool SettingsDialog::getEffectiveBoolValue(const char* section, const char* key, bool default_value) const
{
bool value;
@@ -544,16 +557,12 @@ void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, const
}
std::string filename(VMManager::GetGameSettingsPath(serial, disc_crc));
- std::unique_ptr sif = std::make_unique(std::move(filename));
+ std::unique_ptr sif = std::make_unique(filename);
if (FileSystem::FileExists(sif->GetFileName().c_str()))
sif->Load();
- const QString window_title(tr("%1 [%2]")
- .arg(QtUtils::StringViewToQString(title))
- .arg(QtUtils::StringViewToQString(Path::GetFileName(sif->GetFileName()))));
-
- SettingsDialog* dialog = new SettingsDialog(g_main_window, std::move(sif), game, std::move(serial), disc_crc);
- dialog->setWindowTitle(window_title);
+ SettingsDialog* dialog = new SettingsDialog(g_main_window, std::move(sif), game, std::move(serial), disc_crc, QtUtils::StringViewToQString(Path::GetFileName(filename)));
+ dialog->setWindowTitle(QtUtils::StringViewToQString(title));
dialog->setModal(false);
dialog->show();
}
diff --git a/pcsx2-qt/Settings/SettingsDialog.h b/pcsx2-qt/Settings/SettingsDialog.h
index 398e3ef550..71b0907c16 100644
--- a/pcsx2-qt/Settings/SettingsDialog.h
+++ b/pcsx2-qt/Settings/SettingsDialog.h
@@ -51,7 +51,7 @@ class SettingsDialog final : public QDialog
public:
explicit SettingsDialog(QWidget* parent);
- SettingsDialog(QWidget* parent, std::unique_ptr sif, const GameList::Entry* game, std::string serial, u32 disc_crc);
+ SettingsDialog(QWidget* parent, std::unique_ptr sif, const GameList::Entry* game, std::string serial, u32 disc_crc, QString filename = QString());
~SettingsDialog();
static void openGamePropertiesDialog(const GameList::Entry* game, const std::string_view& title, std::string serial, u32 disc_crc);
@@ -79,6 +79,8 @@ public:
void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text);
bool eventFilter(QObject* object, QEvent* event) override;
+ void setWindowTitle(const QString& title);
+
QString getCategory() const;
void setCategory(const char* category);
@@ -145,6 +147,8 @@ private:
QObject* m_current_help_widget = nullptr;
QMap m_widget_help_text_map;
+ QString m_filename;
+
std::string m_serial;
u32 m_disc_crc;
};
diff --git a/pcsx2/GameList.cpp b/pcsx2/GameList.cpp
index b601da3369..718a90f1c3 100644
--- a/pcsx2/GameList.cpp
+++ b/pcsx2/GameList.cpp
@@ -19,6 +19,7 @@
#include "Elfheader.h"
#include "GameList.h"
#include "Host.h"
+#include "INISettingsInterface.h"
#include "VMManager.h"
#include "common/Assertions.h"
@@ -75,10 +76,10 @@ namespace GameList
static bool GetGameListEntryFromCache(const std::string& path, GameList::Entry* entry);
static void ScanDirectory(const char* path, bool recursive, bool only_cache, const std::vector& excluded_paths,
- const PlayedTimeMap& played_time_map, ProgressCallback* progress);
+ const PlayedTimeMap& played_time_map, const INISettingsInterface& custom_attributes_ini, ProgressCallback* progress);
static bool AddFileFromCache(const std::string& path, std::time_t timestamp, const PlayedTimeMap& played_time_map);
- static bool ScanFile(
- std::string path, std::time_t timestamp, std::unique_lock& lock, const PlayedTimeMap& played_time_map);
+ static bool ScanFile(std::string path, std::time_t timestamp, std::unique_lock& lock,
+ const PlayedTimeMap& played_time_map, const INISettingsInterface& custom_attributes_ini);
static void LoadCache();
static bool LoadEntriesFromCache(std::FILE* stream);
@@ -94,6 +95,8 @@ namespace GameList
static PlayedTimeMap LoadPlayedTimeMap(const std::string& path);
static PlayedTimeEntry UpdatePlayedTimeFile(
const std::string& path, const std::string& serial, std::time_t last_time, std::time_t add_time);
+
+ static std::string GetCustomPropertiesFile();
} // namespace GameList
static std::vector s_entries;
@@ -586,7 +589,7 @@ static bool IsPathExcluded(const std::vector& excluded_paths, const
}
void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache, const std::vector& excluded_paths,
- const PlayedTimeMap& played_time_map, ProgressCallback* progress)
+ const PlayedTimeMap& played_time_map, const INISettingsInterface& custom_attributes_ini, ProgressCallback* progress)
{
Console.WriteLn("Scanning %s%s", path, recursive ? " (recursively)" : "");
@@ -619,7 +622,7 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
}
progress->SetFormattedStatusText("Scanning '%s'...", FileSystem::GetDisplayNameFromPath(ffd.FileName).c_str());
- ScanFile(std::move(ffd.FileName), ffd.ModificationTime, lock, played_time_map);
+ ScanFile(std::move(ffd.FileName), ffd.ModificationTime, lock, played_time_map, custom_attributes_ini);
progress->SetProgressValue(files_scanned);
}
@@ -648,8 +651,8 @@ bool GameList::AddFileFromCache(const std::string& path, std::time_t timestamp,
return true;
}
-bool GameList::ScanFile(
- std::string path, std::time_t timestamp, std::unique_lock& lock, const PlayedTimeMap& played_time_map)
+bool GameList::ScanFile(std::string path, std::time_t timestamp, std::unique_lock& lock,
+ const PlayedTimeMap& played_time_map, const INISettingsInterface& custom_attributes_ini)
{
// don't block UI while scanning
lock.unlock();
@@ -675,13 +678,28 @@ bool GameList::ScanFile(
return true;
}
- auto iter = played_time_map.find(entry.serial);
+ const auto iter = played_time_map.find(entry.serial);
if (iter != played_time_map.end())
{
entry.last_played_time = iter->second.last_played_time;
entry.total_played_time = iter->second.total_played_time;
}
+ auto custom_title = custom_attributes_ini.GetOptionalStringValue(entry.path.c_str(), "Title");
+ if (custom_title)
+ {
+ entry.title = std::move(custom_title.value());
+ }
+ const auto custom_region = custom_attributes_ini.GetOptionalIntValue(entry.path.c_str(), "Region");
+ if (custom_region)
+ {
+ const int custom_region_value = custom_region.value();
+ if (custom_region_value >= 0 && custom_region_value < static_cast(Region::Count))
+ {
+ entry.region = static_cast(custom_region_value);
+ }
+ }
+
lock.lock();
// remove if present
@@ -764,6 +782,8 @@ void GameList::Refresh(bool invalidate_cache, bool only_cache, ProgressCallback*
const std::vector dirs(Host::GetBaseStringListSetting("GameList", "Paths"));
const std::vector recursive_dirs(Host::GetBaseStringListSetting("GameList", "RecursivePaths"));
const PlayedTimeMap played_time(LoadPlayedTimeMap(GetPlayedTimeFile()));
+ INISettingsInterface custom_attributes_ini(GetCustomPropertiesFile());
+ custom_attributes_ini.Load();
if (!dirs.empty() || !recursive_dirs.empty())
{
@@ -777,7 +797,7 @@ void GameList::Refresh(bool invalidate_cache, bool only_cache, ProgressCallback*
if (progress->IsCancelled())
break;
- ScanDirectory(dir.c_str(), false, only_cache, excluded_paths, played_time, progress);
+ ScanDirectory(dir.c_str(), false, only_cache, excluded_paths, played_time, custom_attributes_ini, progress);
progress->SetProgressValue(++directory_counter);
}
for (const std::string& dir : recursive_dirs)
@@ -785,7 +805,7 @@ void GameList::Refresh(bool invalidate_cache, bool only_cache, ProgressCallback*
if (progress->IsCancelled())
break;
- ScanDirectory(dir.c_str(), true, only_cache, excluded_paths, played_time, progress);
+ ScanDirectory(dir.c_str(), true, only_cache, excluded_paths, played_time, custom_attributes_ini, progress);
progress->SetProgressValue(++directory_counter);
}
}
@@ -804,6 +824,8 @@ bool GameList::RescanPath(const std::string& path)
std::unique_lock lock(s_mutex);
const PlayedTimeMap played_time(LoadPlayedTimeMap(GetPlayedTimeFile()));
+ INISettingsInterface custom_attributes_ini(GetCustomPropertiesFile());
+ custom_attributes_ini.Load();
{
// cancel if excluded
@@ -813,7 +835,7 @@ bool GameList::RescanPath(const std::string& path)
}
// re-scan!
- if (!ScanFile(path, sd.ModificationTime, lock, played_time))
+ if (!ScanFile(path, sd.ModificationTime, lock, played_time, custom_attributes_ini))
return true;
// update cache.. this is far from ideal, but since everything's variable length, all we can do.
@@ -1319,3 +1341,74 @@ bool GameList::DownloadCovers(const std::vector& url_templates, boo
return true;
}
+
+std::string GameList::GetCustomPropertiesFile()
+{
+ return Path::Combine(EmuFolders::Settings, "custom_properties.ini");
+}
+
+void GameList::CheckCustomAttributesForPath(const std::string& path, bool& has_custom_title, bool& has_custom_region)
+{
+ INISettingsInterface names(GetCustomPropertiesFile());
+ if (names.Load())
+ {
+ has_custom_title = names.ContainsValue(path.c_str(), "Title");
+ has_custom_region = names.ContainsValue(path.c_str(), "Region");
+ }
+}
+
+void GameList::SaveCustomTitleForPath(const std::string& path, const std::string& custom_title)
+{
+ INISettingsInterface names(GetCustomPropertiesFile());
+ names.Load();
+
+ if (!custom_title.empty())
+ {
+ names.SetStringValue(path.c_str(), "Title", custom_title.c_str());
+ }
+ else
+ {
+ names.DeleteValue(path.c_str(), "Title");
+ }
+
+ if (names.Save())
+ {
+ // Let the cache update by rescanning
+ RescanPath(path);
+ }
+}
+
+void GameList::SaveCustomRegionForPath(const std::string& path, int custom_region)
+{
+ INISettingsInterface names(GetCustomPropertiesFile());
+ names.Load();
+
+ if (custom_region >= 0)
+ {
+ names.SetIntValue(path.c_str(), "Region", custom_region);
+ }
+ else
+ {
+ names.DeleteValue(path.c_str(), "Region");
+ }
+
+ if (names.Save())
+ {
+ // Let the cache update by rescanning
+ RescanPath(path);
+ }
+}
+
+std::string GameList::GetCustomTitleForPath(const std::string& path)
+{
+ std::string ret;
+
+ std::unique_lock lock(s_mutex);
+ const GameList::Entry* entry = GetEntryForPath(path.c_str());
+ if (entry)
+ {
+ ret = entry->title;
+ }
+
+ return ret;
+}
diff --git a/pcsx2/GameList.h b/pcsx2/GameList.h
index 5bd4bbc73d..e5442e7070 100644
--- a/pcsx2/GameList.h
+++ b/pcsx2/GameList.h
@@ -154,4 +154,10 @@ namespace GameList
/// the use_serial parameter. save_callback optionall takes the entry and the path the new cover is saved to.
bool DownloadCovers(const std::vector& url_templates, bool use_serial = false, ProgressCallback* progress = nullptr,
std::function save_callback = {});
+
+ // Custom properties support
+ void CheckCustomAttributesForPath(const std::string& path, bool& has_custom_title, bool& has_custom_region);
+ void SaveCustomTitleForPath(const std::string& path, const std::string& custom_title);
+ void SaveCustomRegionForPath(const std::string& path, int custom_region);
+ std::string GetCustomTitleForPath(const std::string& path);
} // namespace GameList
diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp
index cd51ea82f5..f0745b4361 100644
--- a/pcsx2/VMManager.cpp
+++ b/pcsx2/VMManager.cpp
@@ -849,19 +849,22 @@ void VMManager::UpdateDiscDetails(bool booting)
SaveSessionTime(old_serial);
+ std::string custom_title = GameList::GetCustomTitleForPath(CDVDsys_GetFile(CDVDsys_GetSourceType()));
if (serial_is_valid)
{
if (const GameDatabaseSchema::GameEntry* game = GameDatabase::findGame(s_disc_serial))
{
+ std::string game_title = custom_title.empty() ? game->name : std::move(custom_title);
+
// Append the ELF override if we're using it with a disc.
if (!s_elf_override.empty())
{
title = fmt::format(
- "{} [{}]", game->name, Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(s_elf_override)));
+ "{} [{}]", game_title, Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(s_elf_override)));
}
else
{
- title = game->name;
+ title = std::move(game_title);
}
memcardFilters = game->memcardFiltersAsString();
@@ -872,6 +875,11 @@ void VMManager::UpdateDiscDetails(bool booting)
}
}
+ if (title.empty())
+ {
+ title = std::move(custom_title);
+ }
+
if (title.empty())
{
if (!s_disc_serial.empty())