System: Allow separate configuration for multi-disc games
This commit is contained in:
parent
23c221be01
commit
b634eecd21
|
@ -441,6 +441,7 @@ struct ALIGN_TO_CACHE_LINE UIState
|
|||
// Settings
|
||||
SettingsPage settings_page = SettingsPage::Interface;
|
||||
std::unique_ptr<INISettingsInterface> game_settings_interface;
|
||||
const GameDatabase::Entry* game_settings_db_entry;
|
||||
std::unique_ptr<GameList::Entry> game_settings_entry;
|
||||
std::vector<std::pair<std::string, bool>> game_list_directories_cache;
|
||||
GPUDevice::AdapterInfoList graphics_adapter_list_cache;
|
||||
|
@ -870,8 +871,8 @@ void FullscreenUI::Render()
|
|||
|
||||
if (s_state.game_settings_interface->IsEmpty())
|
||||
{
|
||||
if (FileSystem::FileExists(s_state.game_settings_interface->GetFileName().c_str()) &&
|
||||
!FileSystem::DeleteFile(s_state.game_settings_interface->GetFileName().c_str(), &error))
|
||||
if (FileSystem::FileExists(s_state.game_settings_interface->GetPath().c_str()) &&
|
||||
!FileSystem::DeleteFile(s_state.game_settings_interface->GetPath().c_str(), &error))
|
||||
{
|
||||
ImGuiFullscreen::OpenInfoMessageDialog(
|
||||
FSUI_STR("Error"), fmt::format(FSUI_FSTR("An error occurred while deleting empty game settings:\n{}"),
|
||||
|
@ -2724,6 +2725,7 @@ void FullscreenUI::SwitchToSettings()
|
|||
{
|
||||
s_state.game_settings_entry.reset();
|
||||
s_state.game_settings_interface.reset();
|
||||
s_state.game_settings_db_entry = nullptr;
|
||||
s_state.game_patch_list = {};
|
||||
s_state.enabled_game_patch_cache = {};
|
||||
s_state.game_cheats_list = {};
|
||||
|
@ -2740,8 +2742,9 @@ void FullscreenUI::SwitchToSettings()
|
|||
void FullscreenUI::SwitchToGameSettingsForSerial(std::string_view serial)
|
||||
{
|
||||
s_state.game_settings_entry.reset();
|
||||
s_state.game_settings_interface = std::make_unique<INISettingsInterface>(System::GetGameSettingsPath(serial));
|
||||
s_state.game_settings_interface->Load();
|
||||
s_state.game_settings_db_entry = GameDatabase::GetEntryForSerial(serial);
|
||||
s_state.game_settings_interface =
|
||||
System::GetGameSettingsInterface(s_state.game_settings_db_entry, serial, true, false);
|
||||
PopulatePatchesAndCheatsList(serial);
|
||||
s_state.current_main_window = MainWindowType::Settings;
|
||||
s_state.settings_page = SettingsPage::Summary;
|
||||
|
@ -2828,7 +2831,7 @@ void FullscreenUI::DoCopyGameSettings()
|
|||
SetSettingsChanged(s_state.game_settings_interface.get());
|
||||
|
||||
ShowToast("Game Settings Copied", fmt::format(FSUI_FSTR("Game settings initialized with global settings for '{}'."),
|
||||
Path::GetFileTitle(s_state.game_settings_interface->GetFileName())));
|
||||
Path::GetFileTitle(s_state.game_settings_interface->GetPath())));
|
||||
}
|
||||
|
||||
void FullscreenUI::DoClearGameSettings()
|
||||
|
@ -2837,13 +2840,13 @@ void FullscreenUI::DoClearGameSettings()
|
|||
return;
|
||||
|
||||
s_state.game_settings_interface->Clear();
|
||||
if (!s_state.game_settings_interface->GetFileName().empty())
|
||||
FileSystem::DeleteFile(s_state.game_settings_interface->GetFileName().c_str());
|
||||
if (!s_state.game_settings_interface->GetPath().empty())
|
||||
FileSystem::DeleteFile(s_state.game_settings_interface->GetPath().c_str());
|
||||
|
||||
SetSettingsChanged(s_state.game_settings_interface.get());
|
||||
|
||||
ShowToast("Game Settings Cleared", fmt::format(FSUI_FSTR("Game settings have been cleared for '{}'."),
|
||||
Path::GetFileTitle(s_state.game_settings_interface->GetFileName())));
|
||||
Path::GetFileTitle(s_state.game_settings_interface->GetPath())));
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawSettingsWindow()
|
||||
|
@ -3098,6 +3101,18 @@ void FullscreenUI::DrawSummarySettingsPage()
|
|||
|
||||
MenuHeading(FSUI_CSTR("Options"));
|
||||
|
||||
if (s_state.game_settings_db_entry && !s_state.game_settings_db_entry->disc_set_serials.empty())
|
||||
{
|
||||
// only enable for first disc
|
||||
const bool is_first_disc =
|
||||
(s_state.game_settings_db_entry->serial == s_state.game_settings_db_entry->disc_set_serials.front());
|
||||
DrawToggleSetting(
|
||||
GetEditingSettingsInterface(), FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Use Separate Disc Settings"),
|
||||
FSUI_CSTR(
|
||||
"Uses separate game settings for each disc of multi-disc games. Can only be set on the first/main disc."),
|
||||
"Main", "UseSeparateConfigForDiscSet", !is_first_disc, is_first_disc, false);
|
||||
}
|
||||
|
||||
if (MenuButton(FSUI_ICONSTR(ICON_FA_COPY, "Copy Settings"),
|
||||
FSUI_CSTR("Copies the current global settings to this game.")))
|
||||
{
|
||||
|
|
|
@ -1171,20 +1171,6 @@ DiscRegion System::GetRegionForPsf(const char* path)
|
|||
return psf.GetRegion();
|
||||
}
|
||||
|
||||
std::string System::GetGameSettingsPath(std::string_view game_serial)
|
||||
{
|
||||
// multi-disc games => always use the first disc
|
||||
const GameDatabase::Entry* entry = GameDatabase::GetEntryForSerial(game_serial);
|
||||
const std::string_view serial_for_path =
|
||||
(entry && !entry->disc_set_serials.empty()) ? entry->disc_set_serials.front() : game_serial;
|
||||
return Path::Combine(EmuFolders::GameSettings, fmt::format("{}.ini", Path::SanitizeFileName(serial_for_path)));
|
||||
}
|
||||
|
||||
std::string System::GetInputProfilePath(std::string_view name)
|
||||
{
|
||||
return Path::Combine(EmuFolders::InputProfiles, fmt::format("{}.ini", name));
|
||||
}
|
||||
|
||||
bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_device, bool update_display /* = true*/)
|
||||
{
|
||||
ClearMemorySaveStates();
|
||||
|
@ -1487,27 +1473,108 @@ void System::ReloadInputProfile(bool display_osd_messages)
|
|||
ApplySettings(display_osd_messages);
|
||||
}
|
||||
|
||||
bool System::UpdateGameSettingsLayer()
|
||||
std::string System::GetInputProfilePath(std::string_view name)
|
||||
{
|
||||
std::unique_ptr<INISettingsInterface> new_interface;
|
||||
if (g_settings.apply_game_settings && !s_state.running_game_serial.empty())
|
||||
return Path::Combine(EmuFolders::InputProfiles, fmt::format("{}.ini", name));
|
||||
}
|
||||
|
||||
std::string System::GetGameSettingsPath(std::string_view game_serial, bool ignore_disc_set)
|
||||
{
|
||||
// multi-disc games => always use the first disc
|
||||
const GameDatabase::Entry* entry = ignore_disc_set ? nullptr : GameDatabase::GetEntryForSerial(game_serial);
|
||||
const std::string_view serial_for_path =
|
||||
(entry && !entry->disc_set_serials.empty()) ? entry->disc_set_serials.front() : game_serial;
|
||||
return Path::Combine(EmuFolders::GameSettings, fmt::format("{}.ini", Path::SanitizeFileName(serial_for_path)));
|
||||
}
|
||||
|
||||
std::unique_ptr<INISettingsInterface> System::GetGameSettingsInterface(const GameDatabase::Entry* dbentry,
|
||||
std::string_view serial, bool create, bool quiet)
|
||||
{
|
||||
std::unique_ptr<INISettingsInterface> ret;
|
||||
std::string path = GetGameSettingsPath(serial, false);
|
||||
|
||||
if (FileSystem::FileExists(path.c_str()))
|
||||
{
|
||||
std::string filename(GetGameSettingsPath(s_state.running_game_serial));
|
||||
if (FileSystem::FileExists(filename.c_str()))
|
||||
if (!quiet)
|
||||
INFO_COLOR_LOG(StrongCyan, "Loading game settings from '{}'...", Path::GetFileName(path));
|
||||
|
||||
Error error;
|
||||
ret = std::make_unique<INISettingsInterface>(std::move(path));
|
||||
if (ret->Load(&error))
|
||||
{
|
||||
INFO_LOG("Loading game settings from '{}'...", Path::GetFileName(filename));
|
||||
new_interface = std::make_unique<INISettingsInterface>(std::move(filename));
|
||||
if (!new_interface->Load())
|
||||
// Check for separate disc configuration.
|
||||
if (dbentry && !dbentry->disc_set_serials.empty() && dbentry->disc_set_serials.front() != serial)
|
||||
{
|
||||
ERROR_LOG("Failed to parse game settings ini '{}'", new_interface->GetFileName());
|
||||
new_interface.reset();
|
||||
if (ret->GetBoolValue("Main", "UseSeparateConfigForDiscSet", false))
|
||||
{
|
||||
if (!quiet)
|
||||
{
|
||||
INFO_COLOR_LOG(StrongCyan, "Using separate disc game settings serial {} for disc set {}", serial,
|
||||
dbentry->disc_set_serials.front());
|
||||
}
|
||||
|
||||
// Load the disc specific ini.
|
||||
path = GetGameSettingsPath(serial, true);
|
||||
if (FileSystem::FileExists(path.c_str()))
|
||||
{
|
||||
if (!ret->Load(std::move(path), &error))
|
||||
{
|
||||
if (!quiet)
|
||||
{
|
||||
ERROR_LOG("Failed to parse separate disc game settings ini '{}': {}", Path::GetFileName(ret->GetPath()),
|
||||
error.GetDescription());
|
||||
}
|
||||
|
||||
if (create)
|
||||
ret->Clear();
|
||||
else
|
||||
ret.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!quiet)
|
||||
INFO_COLOR_LOG(StrongCyan, "No separate disc game settings found (tried '{}')", Path::GetFileName(path));
|
||||
|
||||
ret.reset();
|
||||
|
||||
// return empty ini struct?
|
||||
if (create)
|
||||
ret = std::make_unique<INISettingsInterface>(std::move(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG("No game settings found (tried '{}')", Path::GetFileName(filename));
|
||||
if (!quiet)
|
||||
{
|
||||
ERROR_LOG("Failed to parse game settings ini '{}': {}", Path::GetFileName(ret->GetPath()),
|
||||
error.GetDescription());
|
||||
}
|
||||
|
||||
if (!create)
|
||||
ret.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!quiet)
|
||||
INFO_COLOR_LOG(StrongCyan, "No game settings found (tried '{}')", Path::GetFileName(path));
|
||||
|
||||
// return empty ini struct?
|
||||
if (create)
|
||||
ret = std::make_unique<INISettingsInterface>(std::move(path));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool System::UpdateGameSettingsLayer()
|
||||
{
|
||||
std::unique_ptr<INISettingsInterface> new_interface;
|
||||
if (g_settings.apply_game_settings && !s_state.running_game_serial.empty())
|
||||
new_interface = GetGameSettingsInterface(s_state.running_game_entry, s_state.running_game_serial, false, false);
|
||||
|
||||
std::string input_profile_name;
|
||||
if (new_interface)
|
||||
|
@ -1543,7 +1610,7 @@ void System::UpdateInputSettingsLayer(std::string input_profile_name, std::uniqu
|
|||
input_interface = std::make_unique<INISettingsInterface>(std::move(filename));
|
||||
if (!input_interface->Load())
|
||||
{
|
||||
ERROR_LOG("Failed to parse input profile ini '{}'", Path::GetFileName(input_interface->GetFileName()));
|
||||
ERROR_LOG("Failed to parse input profile ini '{}'", Path::GetFileName(input_interface->GetPath()));
|
||||
input_interface.reset();
|
||||
input_profile_name = {};
|
||||
}
|
||||
|
@ -5543,20 +5610,12 @@ std::string System::GetGameMemoryCardPath(std::string_view serial, std::string_v
|
|||
std::unique_ptr<INISettingsInterface> ini;
|
||||
if (!serial.empty())
|
||||
{
|
||||
std::string game_settings_path = GetGameSettingsPath(serial);
|
||||
if (FileSystem::FileExists(game_settings_path.c_str()))
|
||||
ini = GetGameSettingsInterface(GameDatabase::GetEntryForSerial(serial), serial, false, true);
|
||||
if (ini && ini->ContainsValue(section, type_key))
|
||||
{
|
||||
ini = std::make_unique<INISettingsInterface>(std::move(game_settings_path));
|
||||
if (!ini->Load())
|
||||
{
|
||||
ini.reset();
|
||||
}
|
||||
else if (ini->ContainsValue(section, type_key))
|
||||
{
|
||||
type = Settings::ParseMemoryCardTypeName(
|
||||
ini->GetTinyStringValue(section, type_key, Settings::GetMemoryCardTypeName(global_type)))
|
||||
.value_or(global_type);
|
||||
}
|
||||
type = Settings::ParseMemoryCardTypeName(
|
||||
ini->GetTinyStringValue(section, type_key, Settings::GetMemoryCardTypeName(global_type)))
|
||||
.value_or(global_type);
|
||||
}
|
||||
}
|
||||
else if (type == MemoryCardType::PerGame)
|
||||
|
|
|
@ -28,6 +28,7 @@ enum class GPUVSyncMode : u8;
|
|||
class Controller;
|
||||
|
||||
class GPUTexture;
|
||||
class INISettingsInterface;
|
||||
class MediaCapture;
|
||||
|
||||
namespace BIOS {
|
||||
|
@ -153,7 +154,12 @@ DiscRegion GetRegionForExe(const char* path);
|
|||
DiscRegion GetRegionForPsf(const char* path);
|
||||
|
||||
/// Returns the path for the game settings ini file for the specified serial.
|
||||
std::string GetGameSettingsPath(std::string_view game_serial);
|
||||
std::string GetGameSettingsPath(std::string_view game_serial, bool ignore_disc_set);
|
||||
|
||||
/// Returns the loaded interface for the game settings ini file for the specified serial. If create is true, an empty
|
||||
/// ini reader will be returned if the file does not exist. If quit is true, no log messages will be emitted.
|
||||
std::unique_ptr<INISettingsInterface> GetGameSettingsInterface(const GameDatabase::Entry* dbentry,
|
||||
std::string_view serial, bool create, bool quiet);
|
||||
|
||||
/// Returns the path for the input profile ini file with the specified name (may not exist).
|
||||
std::string GetInputProfilePath(std::string_view name);
|
||||
|
|
|
@ -221,7 +221,7 @@ void ControllerSettingsWindow::onNewProfileClicked()
|
|||
{
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("Failed to save the new profile to '%1'.").arg(QString::fromStdString(temp_si.GetFileName())));
|
||||
tr("Failed to save the new profile to '%1'.").arg(QString::fromStdString(temp_si.GetPath())));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,13 @@ GameSummaryWidget::~GameSummaryWidget() = default;
|
|||
|
||||
void GameSummaryWidget::reloadGameSettings()
|
||||
{
|
||||
if (m_ui.separateDiscSettings->isVisible() && m_ui.separateDiscSettings->isEnabled())
|
||||
{
|
||||
m_ui.separateDiscSettings->setCheckState(
|
||||
m_dialog->getBoolValue("Main", "UseSeparateConfigForDiscSet", std::nullopt).value_or(false) ? Qt::Checked :
|
||||
Qt::Unchecked);
|
||||
}
|
||||
|
||||
if (m_dialog->getBoolValue("ControllerPorts", "UseGameSettingsForController", std::nullopt).value_or(false))
|
||||
{
|
||||
const QSignalBlocker sb(m_ui.inputProfile);
|
||||
|
@ -214,6 +221,28 @@ void GameSummaryWidget::populateUi(const std::string& path, const std::string& s
|
|||
m_ui.entryType->setCurrentIndex(static_cast<int>(gentry->type));
|
||||
}
|
||||
|
||||
if (entry && !entry->disc_set_serials.empty())
|
||||
{
|
||||
if (serial == entry->disc_set_serials.front())
|
||||
{
|
||||
m_ui.separateDiscSettings->setCheckState(
|
||||
m_dialog->getBoolValue("Main", "UseSeparateConfigForDiscSet", std::nullopt).value_or(false) ? Qt::Checked :
|
||||
Qt::Unchecked);
|
||||
connect(m_ui.separateDiscSettings, &QCheckBox::checkStateChanged, this,
|
||||
&GameSummaryWidget::onSeparateDiscSettingsChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set disabled+checked if not first disc
|
||||
m_ui.separateDiscSettings->setCheckState(Qt::Checked);
|
||||
m_ui.separateDiscSettings->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui.separateDiscSettings->setVisible(false);
|
||||
}
|
||||
|
||||
m_ui.compatibilityComments->setVisible(!m_compatibility_comments.isEmpty());
|
||||
|
||||
m_ui.inputProfile->addItem(QIcon::fromTheme(QStringLiteral("global-line")), tr("Use Global Settings"));
|
||||
|
@ -228,6 +257,19 @@ void GameSummaryWidget::populateUi(const std::string& path, const std::string& s
|
|||
updateWindowTitle();
|
||||
}
|
||||
|
||||
void GameSummaryWidget::onSeparateDiscSettingsChanged(Qt::CheckState state)
|
||||
{
|
||||
if (state == Qt::Checked)
|
||||
m_dialog->setBoolSettingValue("Main", "UseSeparateConfigForDiscSet", true);
|
||||
else
|
||||
m_dialog->removeSettingValue("Main", "UseSeparateConfigForDiscSet");
|
||||
}
|
||||
|
||||
void GameSummaryWidget::updateWindowTitle()
|
||||
{
|
||||
m_dialog->setGameTitle(m_ui.title->text().toStdString());
|
||||
}
|
||||
|
||||
void GameSummaryWidget::populateCustomAttributes()
|
||||
{
|
||||
auto lock = GameList::GetLock();
|
||||
|
@ -257,11 +299,6 @@ void GameSummaryWidget::populateCustomAttributes()
|
|||
}
|
||||
}
|
||||
|
||||
void GameSummaryWidget::updateWindowTitle()
|
||||
{
|
||||
m_dialog->setGameTitle(m_ui.title->text().toStdString());
|
||||
}
|
||||
|
||||
void GameSummaryWidget::setCustomTitle(const std::string& text)
|
||||
{
|
||||
m_ui.restoreTitle->setEnabled(!text.empty());
|
||||
|
|
|
@ -31,6 +31,7 @@ protected:
|
|||
void showEvent(QShowEvent* event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSeparateDiscSettingsChanged(Qt::CheckState state);
|
||||
void onCustomLanguageChanged(int language);
|
||||
void onCompatibilityCommentsClicked();
|
||||
void onInputProfileChanged(int index);
|
||||
|
|
|
@ -208,13 +208,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="entryType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<item>
|
||||
|
@ -344,6 +337,27 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QComboBox" name="entryType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="separateDiscSettings">
|
||||
<property name="toolTip">
|
||||
<string>Uses separate game settings for each disc of multi-disc games. Can only be set on the first/main disc.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Separate Disc Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -227,14 +227,14 @@ bool QtHost::SaveGameSettings(SettingsInterface* sif, bool delete_if_empty)
|
|||
// if there's no keys, just toss the whole thing out
|
||||
if (delete_if_empty && ini->IsEmpty())
|
||||
{
|
||||
INFO_LOG("Removing empty gamesettings ini {}", Path::GetFileName(ini->GetFileName()));
|
||||
INFO_LOG("Removing empty gamesettings ini {}", Path::GetFileName(ini->GetPath()));
|
||||
|
||||
// grab the settings lock while we're writing the file, that way the CPU thread doesn't try
|
||||
// to read it at the same time.
|
||||
const auto lock = Host::GetSettingsLock();
|
||||
|
||||
if (FileSystem::FileExists(ini->GetFileName().c_str()) &&
|
||||
!FileSystem::DeleteFile(ini->GetFileName().c_str(), &error))
|
||||
if (FileSystem::FileExists(ini->GetPath().c_str()) &&
|
||||
!FileSystem::DeleteFile(ini->GetPath().c_str(), &error))
|
||||
{
|
||||
Host::ReportErrorAsync(
|
||||
TRANSLATE_SV("QtHost", "Error"),
|
||||
|
@ -472,7 +472,7 @@ bool QtHost::InitializeConfig(std::string settings_filename)
|
|||
QStringLiteral(
|
||||
"Failed to save configuration to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You "
|
||||
"can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.")
|
||||
.arg(QString::fromStdString(s_base_settings_interface->GetFileName()))
|
||||
.arg(QString::fromStdString(s_base_settings_interface->GetPath()))
|
||||
.arg(QString::fromStdString(error.GetDescription())));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -662,7 +662,10 @@ void SettingsWindow::setGameTitle(std::string title)
|
|||
{
|
||||
m_title = std::move(title);
|
||||
|
||||
const QString window_title = tr("%1 [%2]").arg(QString::fromStdString(m_title)).arg(QString::fromStdString(m_serial));
|
||||
const QString window_title =
|
||||
tr("%1 [%2]")
|
||||
.arg(QString::fromStdString(m_title))
|
||||
.arg(QtUtils::StringViewToQString(m_sif ? Path::GetFileName(m_sif->GetPath()) : std::string_view(m_serial)));
|
||||
setWindowTitle(window_title);
|
||||
}
|
||||
|
||||
|
@ -695,13 +698,13 @@ SettingsWindow* SettingsWindow::openGamePropertiesDialog(const std::string& path
|
|||
}
|
||||
|
||||
std::string real_serial = dentry ? std::string(dentry->serial) : std::move(serial);
|
||||
std::string ini_filename = System::GetGameSettingsPath(real_serial);
|
||||
std::unique_ptr<INISettingsInterface> sif = System::GetGameSettingsInterface(dentry, real_serial, true, false);
|
||||
|
||||
// check for an existing dialog with this crc
|
||||
// check for an existing dialog with this serial
|
||||
for (SettingsWindow* dialog : s_open_game_properties_dialogs)
|
||||
{
|
||||
if (dialog->isPerGameSettings() &&
|
||||
static_cast<INISettingsInterface*>(dialog->getSettingsInterface())->GetFileName() == ini_filename)
|
||||
static_cast<INISettingsInterface*>(dialog->getSettingsInterface())->GetPath() == sif->GetPath())
|
||||
{
|
||||
dialog->show();
|
||||
dialog->raise();
|
||||
|
@ -713,10 +716,6 @@ SettingsWindow* SettingsWindow::openGamePropertiesDialog(const std::string& path
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<INISettingsInterface> sif = std::make_unique<INISettingsInterface>(std::move(ini_filename));
|
||||
if (FileSystem::FileExists(sif->GetFileName().c_str()))
|
||||
sif->Load();
|
||||
|
||||
SettingsWindow* dialog =
|
||||
new SettingsWindow(path, std::move(title), std::move(real_serial), hash, region, dentry, std::move(sif));
|
||||
dialog->show();
|
||||
|
@ -737,14 +736,14 @@ void SettingsWindow::closeGamePropertiesDialogs()
|
|||
bool SettingsWindow::setGameSettingsBoolForSerial(const std::string& serial, const char* section, const char* key,
|
||||
bool value)
|
||||
{
|
||||
std::string ini_filename = System::GetGameSettingsPath(serial);
|
||||
if (ini_filename.empty())
|
||||
if (serial.empty())
|
||||
return false;
|
||||
|
||||
INISettingsInterface sif(std::move(ini_filename));
|
||||
if (FileSystem::FileExists(sif.GetFileName().c_str()))
|
||||
sif.Load();
|
||||
std::unique_ptr<INISettingsInterface> sif =
|
||||
System::GetGameSettingsInterface(GameDatabase::GetEntryForSerial(serial), serial, true, false);
|
||||
if (!sif)
|
||||
return false;
|
||||
|
||||
sif.SetBoolValue(section, key, value);
|
||||
return sif.Save();
|
||||
sif->SetBoolValue(section, key, value);
|
||||
return sif->Save();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ LOG_CHANNEL(Settings);
|
|||
// we only allow one ini to be parsed at any point in time.
|
||||
static std::mutex s_ini_load_save_mutex;
|
||||
|
||||
INISettingsInterface::INISettingsInterface(std::string filename) : m_filename(std::move(filename)), m_ini(true, true)
|
||||
INISettingsInterface::INISettingsInterface(std::string filename) : m_path(std::move(filename)), m_ini(true, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ INISettingsInterface::~INISettingsInterface()
|
|||
|
||||
bool INISettingsInterface::Load(Error* error /* = nullptr */)
|
||||
{
|
||||
if (m_filename.empty())
|
||||
if (m_path.empty())
|
||||
{
|
||||
Error::SetStringView(error, "Filename is not set.");
|
||||
return false;
|
||||
|
@ -39,7 +39,7 @@ bool INISettingsInterface::Load(Error* error /* = nullptr */)
|
|||
|
||||
std::unique_lock lock(s_ini_load_save_mutex);
|
||||
SI_Error err = SI_FAIL;
|
||||
auto fp = FileSystem::OpenManagedCFile(m_filename.c_str(), "rb", error);
|
||||
auto fp = FileSystem::OpenManagedCFile(m_path.c_str(), "rb", error);
|
||||
if (fp)
|
||||
{
|
||||
err = m_ini.LoadFile(fp.get());
|
||||
|
@ -50,16 +50,23 @@ bool INISettingsInterface::Load(Error* error /* = nullptr */)
|
|||
return (err == SI_OK);
|
||||
}
|
||||
|
||||
bool INISettingsInterface::Load(std::string new_path, Error* error /*= nullptr*/)
|
||||
{
|
||||
m_path = std::move(new_path);
|
||||
m_ini.Reset();
|
||||
return Load(error);
|
||||
}
|
||||
|
||||
bool INISettingsInterface::Save(Error* error /* = nullptr */)
|
||||
{
|
||||
if (m_filename.empty())
|
||||
if (m_path.empty())
|
||||
{
|
||||
Error::SetStringView(error, "Filename is not set.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_lock lock(s_ini_load_save_mutex);
|
||||
FileSystem::AtomicRenamedFile fp = FileSystem::CreateAtomicRenamedFile(m_filename, error);
|
||||
FileSystem::AtomicRenamedFile fp = FileSystem::CreateAtomicRenamedFile(m_path, error);
|
||||
SI_Error err = SI_FAIL;
|
||||
if (fp)
|
||||
{
|
||||
|
@ -78,7 +85,7 @@ bool INISettingsInterface::Save(Error* error /* = nullptr */)
|
|||
|
||||
if (err != SI_OK)
|
||||
{
|
||||
WARNING_LOG("Failed to save settings to '{}'.", m_filename);
|
||||
WARNING_LOG("Failed to save settings to '{}'.", m_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
class INISettingsInterface final : public SettingsInterface
|
||||
{
|
||||
public:
|
||||
INISettingsInterface(std::string filename);
|
||||
INISettingsInterface(std::string path);
|
||||
~INISettingsInterface() override;
|
||||
|
||||
const std::string& GetFileName() const { return m_filename; }
|
||||
const std::string& GetPath() const { return m_path; }
|
||||
|
||||
bool Load(Error* error = nullptr);
|
||||
bool Load(std::string new_path, Error* error = nullptr);
|
||||
bool Save(Error* error = nullptr) override;
|
||||
|
||||
void Clear() override;
|
||||
|
@ -61,7 +62,7 @@ public:
|
|||
using SettingsInterface::GetUIntValue;
|
||||
|
||||
private:
|
||||
std::string m_filename;
|
||||
std::string m_path;
|
||||
CSimpleIniA m_ini;
|
||||
bool m_dirty = false;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue