mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-18 08:19:59 +00:00
Merge 3d546ac7ed
into e6ed939952
This commit is contained in:
commit
beccb41444
4 changed files with 86 additions and 43 deletions
|
@ -139,10 +139,6 @@ Java_org_dolphinemu_dolphinemu_features_settings_model_NativeConfig_unloadGameIn
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_settings_model_NativeConfig_save(
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_settings_model_NativeConfig_save(
|
||||||
JNIEnv*, jclass, jint layer)
|
JNIEnv*, jclass, jint layer)
|
||||||
{
|
{
|
||||||
// HostThreadLock is used to ensure we don't try to save to SYSCONF at the same time as
|
|
||||||
// emulation shutdown does
|
|
||||||
HostThreadLock guard;
|
|
||||||
|
|
||||||
return GetLayer(layer, {})->Save();
|
return GetLayer(layer, {})->Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "Core/AchievementManager.h"
|
#include "Core/AchievementManager.h"
|
||||||
#include "Core/Boot/Boot.h"
|
#include "Core/Boot/Boot.h"
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
#include "Core/Config/SYSCONFSettings.h"
|
|
||||||
#include "Core/ConfigLoaders/BaseConfigLoader.h"
|
#include "Core/ConfigLoaders/BaseConfigLoader.h"
|
||||||
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
|
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
@ -148,6 +147,8 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
||||||
|
|
||||||
Core::UpdateWantDeterminism(system, /*initial*/ true);
|
Core::UpdateWantDeterminism(system, /*initial*/ true);
|
||||||
|
|
||||||
|
ConfigLoaders::TransferSYSCONFControlToGuest();
|
||||||
|
|
||||||
if (system.IsWii())
|
if (system.IsWii())
|
||||||
{
|
{
|
||||||
Core::InitializeWiiRoot(Core::WantsDeterminism());
|
Core::InitializeWiiRoot(Core::WantsDeterminism());
|
||||||
|
@ -156,13 +157,16 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
||||||
if (!Core::WantsDeterminism())
|
if (!Core::WantsDeterminism())
|
||||||
{
|
{
|
||||||
Core::BackupWiiSettings();
|
Core::BackupWiiSettings();
|
||||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta);
|
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta,
|
||||||
|
ConfigLoaders::SkipIfControlledByGuest::No);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta, [](const Config::Location& location) {
|
ConfigLoaders::SaveToSYSCONF(
|
||||||
return Config::GetActiveLayerForConfig(location) >= Config::LayerType::Movie;
|
Config::LayerType::Meta, ConfigLoaders::SkipIfControlledByGuest::No,
|
||||||
});
|
[](const Config::Location& location) {
|
||||||
|
return Config::GetActiveLayerForConfig(location) >= Config::LayerType::Movie;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,35 +187,6 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
||||||
return Core::Init(system, std::move(boot), wsi);
|
return Core::Init(system, std::move(boot), wsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SYSCONF can be modified during emulation by the user and internally, which makes it
|
|
||||||
// a bad idea to just always overwrite it with the settings from the base layer.
|
|
||||||
//
|
|
||||||
// Conversely, we also shouldn't just accept any changes to SYSCONF, as it may cause
|
|
||||||
// temporary settings (from Movie, Netplay, game INIs, etc.) to stick around.
|
|
||||||
//
|
|
||||||
// To avoid inconveniences in most cases, we accept changes that aren't being overridden by a
|
|
||||||
// non-base layer, and restore only the overridden settings.
|
|
||||||
static void RestoreSYSCONF()
|
|
||||||
{
|
|
||||||
// This layer contains the new SYSCONF settings (including any temporary settings).
|
|
||||||
Config::Layer temp_layer(Config::LayerType::Base);
|
|
||||||
// Use a separate loader so the temp layer doesn't automatically save
|
|
||||||
ConfigLoaders::GenerateBaseConfigLoader()->Load(&temp_layer);
|
|
||||||
|
|
||||||
for (const auto& setting : Config::SYSCONF_SETTINGS)
|
|
||||||
{
|
|
||||||
std::visit(
|
|
||||||
[&](auto* info) {
|
|
||||||
// If this setting was overridden, then we copy the base layer value back to the SYSCONF.
|
|
||||||
// Otherwise we leave the new value in the SYSCONF.
|
|
||||||
if (Config::GetActiveLayerForConfig(*info) == Config::LayerType::Base)
|
|
||||||
Config::SetBase(*info, temp_layer.Get(*info));
|
|
||||||
},
|
|
||||||
setting.config_info);
|
|
||||||
}
|
|
||||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RestoreConfig()
|
void RestoreConfig()
|
||||||
{
|
{
|
||||||
Core::ShutdownWiiRoot();
|
Core::ShutdownWiiRoot();
|
||||||
|
@ -219,7 +194,11 @@ void RestoreConfig()
|
||||||
if (!Core::WiiRootIsTemporary())
|
if (!Core::WiiRootIsTemporary())
|
||||||
{
|
{
|
||||||
Core::RestoreWiiSettings(Core::RestoreReason::EmulationEnd);
|
Core::RestoreWiiSettings(Core::RestoreReason::EmulationEnd);
|
||||||
RestoreSYSCONF();
|
ConfigLoaders::TransferSYSCONFControlFromGuest(ConfigLoaders::WriteBackChangedValues::Yes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConfigLoaders::TransferSYSCONFControlFromGuest(ConfigLoaders::WriteBackChangedValues::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::ClearCurrentRunLayer();
|
Config::ClearCurrentRunLayer();
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Config/Config.h"
|
#include "Common/Config/Config.h"
|
||||||
|
#include "Common/Config/Layer.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/IniFile.h"
|
#include "Common/IniFile.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -23,17 +25,67 @@
|
||||||
#include "Core/Config/SYSCONFSettings.h"
|
#include "Core/Config/SYSCONFSettings.h"
|
||||||
#include "Core/ConfigLoaders/IsSettingSaveable.h"
|
#include "Core/ConfigLoaders/IsSettingSaveable.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
#include "Core/IOS/USB/Bluetooth/BTBase.h"
|
#include "Core/IOS/USB/Bluetooth/BTBase.h"
|
||||||
#include "Core/SysConf.h"
|
#include "Core/SysConf.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
static bool s_sysconf_controlled_by_guest = false;
|
||||||
|
static std::recursive_mutex s_sysconf_lock;
|
||||||
|
|
||||||
namespace ConfigLoaders
|
namespace ConfigLoaders
|
||||||
{
|
{
|
||||||
void SaveToSYSCONF(Config::LayerType layer, std::function<bool(const Config::Location&)> predicate)
|
void TransferSYSCONFControlToGuest()
|
||||||
{
|
{
|
||||||
if (Core::IsRunning(Core::System::GetInstance()))
|
std::lock_guard lock(s_sysconf_lock);
|
||||||
|
|
||||||
|
ASSERT(!s_sysconf_controlled_by_guest);
|
||||||
|
s_sysconf_controlled_by_guest = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferSYSCONFControlFromGuest(WriteBackChangedValues write_back_changed_values)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(s_sysconf_lock);
|
||||||
|
|
||||||
|
ASSERT(s_sysconf_controlled_by_guest);
|
||||||
|
s_sysconf_controlled_by_guest = false;
|
||||||
|
|
||||||
|
if (write_back_changed_values == WriteBackChangedValues::Yes)
|
||||||
|
{
|
||||||
|
// SYSCONF can be modified during emulation by the user and internally, which makes it
|
||||||
|
// a bad idea to just always overwrite it with the settings from the base layer.
|
||||||
|
//
|
||||||
|
// Conversely, we also shouldn't just accept any changes to SYSCONF, as it may cause
|
||||||
|
// temporary settings (from Movie, Netplay, game INIs, etc.) to stick around.
|
||||||
|
//
|
||||||
|
// To avoid inconveniences in most cases, we accept changes that aren't being overridden by a
|
||||||
|
// non-base layer, and restore only the overridden settings.
|
||||||
|
|
||||||
|
// This layer contains the new SYSCONF settings (including any temporary settings).
|
||||||
|
Config::Layer temp_layer(Config::LayerType::Base);
|
||||||
|
// Use a separate loader so the temp layer doesn't automatically save
|
||||||
|
GenerateBaseConfigLoader()->Load(&temp_layer);
|
||||||
|
|
||||||
|
for (const auto& setting : Config::SYSCONF_SETTINGS)
|
||||||
|
{
|
||||||
|
std::visit(
|
||||||
|
[&](auto* info) {
|
||||||
|
// If this setting was overridden, then we copy the base layer value back to the
|
||||||
|
// SYSCONF. Otherwise we leave the new value in the SYSCONF.
|
||||||
|
if (Config::GetActiveLayerForConfig(*info) == Config::LayerType::Base)
|
||||||
|
Config::SetBase(*info, temp_layer.Get(*info));
|
||||||
|
},
|
||||||
|
setting.config_info);
|
||||||
|
}
|
||||||
|
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveToSYSCONF(Config::LayerType layer, SkipIfControlledByGuest skip,
|
||||||
|
std::function<bool(const Config::Location&)> predicate)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(s_sysconf_lock);
|
||||||
|
if (skip != SkipIfControlledByGuest::No && s_sysconf_controlled_by_guest)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IOS::HLE::Kernel ios;
|
IOS::HLE::Kernel ios;
|
||||||
|
@ -182,7 +234,8 @@ public:
|
||||||
private:
|
private:
|
||||||
void LoadFromSYSCONF(Config::Layer* layer)
|
void LoadFromSYSCONF(Config::Layer* layer)
|
||||||
{
|
{
|
||||||
if (Core::IsRunning(Core::System::GetInstance()))
|
std::lock_guard lock(s_sysconf_lock);
|
||||||
|
if (s_sysconf_controlled_by_guest)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IOS::HLE::Kernel ios;
|
IOS::HLE::Kernel ios;
|
||||||
|
|
|
@ -15,7 +15,22 @@ struct Location;
|
||||||
|
|
||||||
namespace ConfigLoaders
|
namespace ConfigLoaders
|
||||||
{
|
{
|
||||||
|
enum class WriteBackChangedValues
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SkipIfControlledByGuest
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
|
||||||
|
void TransferSYSCONFControlToGuest();
|
||||||
|
void TransferSYSCONFControlFromGuest(WriteBackChangedValues write_back_changed_values);
|
||||||
void SaveToSYSCONF(Config::LayerType layer,
|
void SaveToSYSCONF(Config::LayerType layer,
|
||||||
|
SkipIfControlledByGuest skip = SkipIfControlledByGuest::Yes,
|
||||||
std::function<bool(const Config::Location&)> predicate = {});
|
std::function<bool(const Config::Location&)> predicate = {});
|
||||||
std::unique_ptr<Config::ConfigLayerLoader> GenerateBaseConfigLoader();
|
std::unique_ptr<Config::ConfigLayerLoader> GenerateBaseConfigLoader();
|
||||||
} // namespace ConfigLoaders
|
} // namespace ConfigLoaders
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue