diff --git a/pcsx2-qt/MainWindow.cpp b/pcsx2-qt/MainWindow.cpp index c9dfc6faad..e77b164252 100644 --- a/pcsx2-qt/MainWindow.cpp +++ b/pcsx2-qt/MainWindow.cpp @@ -897,7 +897,7 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point) QAction* action = menu.addAction(tr("Properties...")); action->setEnabled(!entry->serial.empty()); if (action->isEnabled()) - connect(action, &QAction::triggered, [entry]() { SettingsDialog::openGamePropertiesDialog(entry, entry->crc); }); + connect(action, &QAction::triggered, [entry]() { SettingsDialog::openGamePropertiesDialog(entry, entry->serial, entry->crc); }); action = menu.addAction(tr("Open Containing Directory...")); connect(action, &QAction::triggered, [this, entry]() { @@ -1074,14 +1074,14 @@ void MainWindow::onViewGamePropertiesActionTriggered() const GameList::Entry* entry = GameList::GetEntryForPath(m_current_disc_path.toUtf8().constData()); if (entry) { - SettingsDialog::openGamePropertiesDialog(entry, entry->crc); + SettingsDialog::openGamePropertiesDialog(entry, entry->serial, entry->crc); return; } } // open properties for the current running file (isn't in the game list) if (m_current_game_crc != 0) - SettingsDialog::openGamePropertiesDialog(nullptr, m_current_game_crc); + SettingsDialog::openGamePropertiesDialog(nullptr, m_current_game_serial.toStdString(), m_current_game_crc); } void MainWindow::onGitHubRepositoryActionTriggered() diff --git a/pcsx2-qt/Settings/SettingsDialog.cpp b/pcsx2-qt/Settings/SettingsDialog.cpp index fe00f6c5aa..7d6b29cef4 100644 --- a/pcsx2-qt/Settings/SettingsDialog.cpp +++ b/pcsx2-qt/Settings/SettingsDialog.cpp @@ -414,7 +414,7 @@ void SettingsDialog::setStringSettingValue(const char* section, const char* key, g_emu_thread->applySettings(); } -void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, u32 crc) +void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, const std::string_view& serial, u32 crc) { // check for an existing dialog with this crc for (SettingsDialog* dialog : s_open_game_properties_dialogs) @@ -427,8 +427,8 @@ void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, u32 c } } - std::unique_ptr sif = - std::make_unique(Path::Combine(EmuFolders::GameSettings, StringUtil::StdStringFromFormat("%08X.ini", crc))); + std::string filename(VMManager::GetGameSettingsPath(serial, crc)); + std::unique_ptr sif = std::make_unique(std::move(filename)); if (FileSystem::FileExists(sif->GetFileName().c_str())) sif->Load(); diff --git a/pcsx2-qt/Settings/SettingsDialog.h b/pcsx2-qt/Settings/SettingsDialog.h index e6a4efb81c..0cf4f4e16c 100644 --- a/pcsx2-qt/Settings/SettingsDialog.h +++ b/pcsx2-qt/Settings/SettingsDialog.h @@ -50,7 +50,7 @@ public: SettingsDialog(std::unique_ptr sif, const GameList::Entry* game, u32 game_crc); ~SettingsDialog(); - static void openGamePropertiesDialog(const GameList::Entry* game, u32 crc); + static void openGamePropertiesDialog(const GameList::Entry* game, const std::string_view& serial, u32 crc); __fi bool isPerGameSettings() const { return static_cast(m_sif); } __fi SettingsInterface* getSettingsInterface() const { return m_sif.get(); } diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 3b6e39b279..b2b24419f0 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -285,9 +285,14 @@ void VMManager::ApplyGameFixes() s_active_game_fixes += game->applyGSHardwareFixes(EmuConfig.GS); } -std::string VMManager::GetGameSettingsPath(u32 game_crc) +std::string VMManager::GetGameSettingsPath(const std::string_view& game_serial, u32 game_crc) { - return Path::Combine(EmuFolders::GameSettings, StringUtil::StdStringFromFormat("%08X.ini", game_crc)); + std::string sanitized_serial(game_serial); + Path::SanitizeFileName(sanitized_serial); + + return game_serial.empty() ? + Path::Combine(EmuFolders::GameSettings, fmt::format("{:08X}.ini", game_crc)) : + Path::Combine(EmuFolders::GameSettings, fmt::format("{}_{:08X}.ini", sanitized_serial, game_crc)); } void VMManager::RequestDisplaySize(float scale /*= 0.0f*/) @@ -341,7 +346,13 @@ bool VMManager::UpdateGameSettingsLayer() std::unique_ptr new_interface; if (s_game_crc != 0) { - const std::string filename(GetGameSettingsPath(s_game_crc)); + std::string filename(GetGameSettingsPath(s_game_serial.c_str(), s_game_crc)); + if (!FileSystem::FileExists(filename.c_str())) + { + // try the legacy format (crc.ini) + filename = GetGameSettingsPath({}, s_game_crc); + } + if (FileSystem::FileExists(filename.c_str())) { Console.WriteLn("Loading game settings from '%s'...", filename.c_str()); diff --git a/pcsx2/VMManager.h b/pcsx2/VMManager.h index 227d980389..8e516be542 100644 --- a/pcsx2/VMManager.h +++ b/pcsx2/VMManager.h @@ -141,7 +141,7 @@ namespace VMManager bool IsGSDumpFileName(const std::string& path); /// Returns the path for the game settings ini file for the specified CRC. - std::string GetGameSettingsPath(u32 game_crc); + std::string GetGameSettingsPath(const std::string_view& game_serial, u32 game_crc); /// Resizes the render window to the display size, with an optional scale. /// If the scale is set to 0, the internal resolution will be used, otherwise it is treated as a multiplier to 1x.