From d9893bb127824a89588258f0561e20eb2e8d93c1 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 15 Aug 2020 20:38:54 +1000 Subject: [PATCH] System: Add option to use a single memory card for playlists --- src/core/host_interface.cpp | 5 ++- src/core/settings.cpp | 2 ++ src/core/settings.h | 1 + src/core/system.cpp | 12 ++++++- src/core/system.h | 3 ++ .../memorycardsettingswidget.cpp | 35 +++++++++++++------ src/duckstation-qt/memorycardsettingswidget.h | 7 ++-- src/duckstation-qt/settingsdialog.cpp | 2 +- 8 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index acbe22aa6..f18cbd292 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -410,6 +410,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetStringValue("MemoryCards", "Card1Path", "memcards/shared_card_1.mcd"); si.SetStringValue("MemoryCards", "Card2Type", Settings::GetMemoryCardTypeName(Settings::DEFAULT_MEMORY_CARD_2_TYPE)); si.SetStringValue("MemoryCards", "Card2Path", "memcards/shared_card_2.mcd"); + si.SetBoolValue("MemoryCards", "UsePlaylistTitle", true); si.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Settings::DEFAULT_LOG_LEVEL)); si.SetStringValue("Logging", "LogFilter", ""); @@ -519,7 +520,9 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings) g_cdrom.SetUseReadThread(g_settings.cdrom_read_thread); if (g_settings.memory_card_types != old_settings.memory_card_types || - g_settings.memory_card_paths != old_settings.memory_card_paths) + g_settings.memory_card_paths != old_settings.memory_card_paths || + (g_settings.memory_card_use_playlist_title != old_settings.memory_card_use_playlist_title && + System::HasMediaPlaylist())) { System::UpdateMemoryCards(); } diff --git a/src/core/settings.cpp b/src/core/settings.cpp index e4c7abfd8..ecae7daf3 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -164,6 +164,7 @@ void Settings::Load(SettingsInterface& si) si.GetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(DEFAULT_MEMORY_CARD_2_TYPE)).c_str()) .value_or(DEFAULT_MEMORY_CARD_2_TYPE); memory_card_paths[1] = si.GetStringValue("MemoryCards", "Card2Path", "memcards/shared_card_2.mcd"); + memory_card_use_playlist_title = si.GetBoolValue("MemoryCards", "UsePlaylistTitle", true); log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str()) .value_or(DEFAULT_LOG_LEVEL); @@ -258,6 +259,7 @@ void Settings::Save(SettingsInterface& si) const si.SetStringValue("MemoryCards", "Card1Path", memory_card_paths[0].c_str()); si.SetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(memory_card_types[1])); si.SetStringValue("MemoryCards", "Card2Path", memory_card_paths[1].c_str()); + si.SetBoolValue("MemoryCards", "UsePlaylistTitle", memory_card_use_playlist_title); si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level)); si.SetStringValue("Logging", "LogFilter", log_filter.c_str()); diff --git a/src/core/settings.h b/src/core/settings.h index 4aa068289..c936b5e88 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -143,6 +143,7 @@ struct Settings std::array controller_types{}; std::array memory_card_types{}; std::array memory_card_paths{}; + bool memory_card_use_playlist_title = true; LOGLEVEL log_level = LOGLEVEL_INFO; std::string log_filter; diff --git a/src/core/system.cpp b/src/core/system.cpp index 0ab0def47..53da3551a 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1187,7 +1187,12 @@ void UpdateMemoryCards() case MemoryCardType::PerGameTitle: { - if (s_running_game_title.empty()) + if (!s_media_playlist_filename.empty() && g_settings.memory_card_use_playlist_title) + { + const std::string playlist_title(GameList::GetTitleForPath(s_media_playlist_filename.c_str())); + card = MemoryCard::Open(g_host_interface->GetGameMemoryCardPath(playlist_title.c_str(), i)); + } + else if (s_running_game_title.empty()) { g_host_interface->AddFormattedOSDMessage(5.0f, "Per-game memory card cannot be used for slot %u as the running " @@ -1268,6 +1273,11 @@ void UpdateRunningGame(const char* path, CDImage* image) g_host_interface->OnRunningGameChanged(); } +bool HasMediaPlaylist() +{ + return !s_media_playlist_filename.empty(); +} + u32 GetMediaPlaylistCount() { return static_cast(s_media_playlist.size()); diff --git a/src/core/system.h b/src/core/system.h index 1f0585016..551247f6f 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -108,6 +108,9 @@ bool HasMedia(); bool InsertMedia(const char* path); void RemoveMedia(); +/// Returns true if a playlist is being used. +bool HasMediaPlaylist(); + /// Returns the number of entries in the media/disc playlist. u32 GetMediaPlaylistCount(); diff --git a/src/duckstation-qt/memorycardsettingswidget.cpp b/src/duckstation-qt/memorycardsettingswidget.cpp index b4bb1e134..fc7730424 100644 --- a/src/duckstation-qt/memorycardsettingswidget.cpp +++ b/src/duckstation-qt/memorycardsettingswidget.cpp @@ -5,6 +5,7 @@ #include "inputbindingwidgets.h" #include "qthostinterface.h" #include "qtutils.h" +#include "settingsdialog.h" #include "settingwidgetbinder.h" #include #include @@ -12,39 +13,53 @@ static constexpr char MEMORY_CARD_IMAGE_FILTER[] = "All Memory Card Types (*.mcd *.mcr *.mc)"; -MemoryCardSettingsWidget::MemoryCardSettingsWidget(QtHostInterface* host_interface, QWidget* parent /* = nullptr */) +MemoryCardSettingsWidget::MemoryCardSettingsWidget(QtHostInterface* host_interface, QWidget* parent, + SettingsDialog* dialog) : QWidget(parent), m_host_interface(host_interface) { - createUi(); + createUi(dialog); } MemoryCardSettingsWidget::~MemoryCardSettingsWidget() = default; -void MemoryCardSettingsWidget::createUi() +void MemoryCardSettingsWidget::createUi(SettingsDialog* dialog) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); for (int i = 0; i < static_cast(m_port_ui.size()); i++) { - createPortSettingsUi(i, &m_port_ui[i]); + createPortSettingsUi(dialog, i, &m_port_ui[i]); layout->addWidget(m_port_ui[i].container); } { - QGroupBox* note_box = new QGroupBox(this); - QHBoxLayout* note_layout = new QHBoxLayout(note_box); + QGroupBox* box = new QGroupBox(tr("Shared Settings"), this); + QVBoxLayout* box_layout = new QVBoxLayout(box); + + QCheckBox* playlist_title_as_game_title = new QCheckBox(tr("Use Single Card For Playlist"), box); + SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, playlist_title_as_game_title, "MemoryCards", + "UsePlaylistTitle", true); + box_layout->addWidget(playlist_title_as_game_title); + dialog->registerWidgetHelp( + playlist_title_as_game_title, tr("Use Single Card For Playlist"), tr("Checked"), + tr("When using a playlist (m3u) and per-game (title) memory cards, a single memory card " + "will be used for all discs. If unchecked, a separate card will be used for each disc.")); + + QHBoxLayout* note_layout = new QHBoxLayout(); QLabel* note_label = new QLabel(tr("If one of the \"separate card per game\" memory card modes is chosen, these memory " "cards will be saved to the memcards directory."), - note_box); + box); note_label->setWordWrap(true); note_layout->addWidget(note_label, 1); - QPushButton* open_memcards = new QPushButton(tr("Open..."), note_box); + QPushButton* open_memcards = new QPushButton(tr("Open..."), box); connect(open_memcards, &QPushButton::clicked, this, &MemoryCardSettingsWidget::onOpenMemCardsDirectoryClicked); note_layout->addWidget(open_memcards); - layout->addWidget(note_box); + box_layout->addLayout(note_layout); + + layout->addWidget(box); } layout->addStretch(1); @@ -52,7 +67,7 @@ void MemoryCardSettingsWidget::createUi() setLayout(layout); } -void MemoryCardSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* ui) +void MemoryCardSettingsWidget::createPortSettingsUi(SettingsDialog* dialog, int index, PortSettingsUI* ui) { ui->container = new QGroupBox(tr("Memory Card %1").arg(index + 1), this); ui->layout = new QVBoxLayout(ui->container); diff --git a/src/duckstation-qt/memorycardsettingswidget.h b/src/duckstation-qt/memorycardsettingswidget.h index 82971b29f..bc0109619 100644 --- a/src/duckstation-qt/memorycardsettingswidget.h +++ b/src/duckstation-qt/memorycardsettingswidget.h @@ -9,13 +9,14 @@ #include class QtHostInterface; +class SettingsDialog; class MemoryCardSettingsWidget : public QWidget { Q_OBJECT public: - MemoryCardSettingsWidget(QtHostInterface* host_interface, QWidget* parent = nullptr); + MemoryCardSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog); ~MemoryCardSettingsWidget(); private: @@ -29,8 +30,8 @@ private: QLineEdit* memory_card_path; }; - void createUi(); - void createPortSettingsUi(int index, PortSettingsUI* ui); + void createUi(SettingsDialog* dialog); + void createPortSettingsUi(SettingsDialog* dialog, int index, PortSettingsUI* ui); void onBrowseMemoryCardPathClicked(int index); void onOpenMemCardsDirectoryClicked(); diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp index 4158837b3..70187f43d 100644 --- a/src/duckstation-qt/settingsdialog.cpp +++ b/src/duckstation-qt/settingsdialog.cpp @@ -26,7 +26,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent m_game_list_settings = new GameListSettingsWidget(host_interface, m_ui.settingsContainer); m_hotkey_settings = new HotkeySettingsWidget(host_interface, m_ui.settingsContainer); m_controller_settings = new ControllerSettingsWidget(host_interface, m_ui.settingsContainer); - m_memory_card_settings = new MemoryCardSettingsWidget(host_interface, m_ui.settingsContainer); + m_memory_card_settings = new MemoryCardSettingsWidget(host_interface, m_ui.settingsContainer, this); m_gpu_settings = new GPUSettingsWidget(host_interface, m_ui.settingsContainer, this); m_audio_settings = new AudioSettingsWidget(host_interface, m_ui.settingsContainer, this); m_advanced_settings = new AdvancedSettingsWidget(host_interface, m_ui.settingsContainer, this);