Merge pull request #6154 from MerryMage/config-cleanup
Cleanup implementation of onion configuration
This commit is contained in:
commit
84ca9a4aec
|
@ -4,8 +4,8 @@ set(SRCS
|
||||||
ColorUtil.cpp
|
ColorUtil.cpp
|
||||||
CommonFuncs.cpp
|
CommonFuncs.cpp
|
||||||
Config/Config.cpp
|
Config/Config.cpp
|
||||||
|
Config/ConfigInfo.cpp
|
||||||
Config/Layer.cpp
|
Config/Layer.cpp
|
||||||
Config/Section.cpp
|
|
||||||
Crypto/AES.cpp
|
Crypto/AES.cpp
|
||||||
Crypto/bn.cpp
|
Crypto/bn.cpp
|
||||||
Crypto/ec.cpp
|
Crypto/ec.cpp
|
||||||
|
@ -29,8 +29,8 @@ set(SRCS
|
||||||
PcapFile.cpp
|
PcapFile.cpp
|
||||||
PerformanceCounter.cpp
|
PerformanceCounter.cpp
|
||||||
Profiler.cpp
|
Profiler.cpp
|
||||||
SettingsHandler.cpp
|
|
||||||
SDCardUtil.cpp
|
SDCardUtil.cpp
|
||||||
|
SettingsHandler.cpp
|
||||||
StringUtil.cpp
|
StringUtil.cpp
|
||||||
SymbolDB.cpp
|
SymbolDB.cpp
|
||||||
SysConf.cpp
|
SysConf.cpp
|
||||||
|
|
|
@ -55,9 +55,9 @@
|
||||||
<ClInclude Include="CommonPaths.h" />
|
<ClInclude Include="CommonPaths.h" />
|
||||||
<ClInclude Include="CommonTypes.h" />
|
<ClInclude Include="CommonTypes.h" />
|
||||||
<ClInclude Include="Config\Config.h" />
|
<ClInclude Include="Config\Config.h" />
|
||||||
|
<ClInclude Include="Config\ConfigInfo.h" />
|
||||||
<ClInclude Include="Config\Enums.h" />
|
<ClInclude Include="Config\Enums.h" />
|
||||||
<ClInclude Include="Config\Layer.h" />
|
<ClInclude Include="Config\Layer.h" />
|
||||||
<ClInclude Include="Config\Section.h" />
|
|
||||||
<ClInclude Include="CPUDetect.h" />
|
<ClInclude Include="CPUDetect.h" />
|
||||||
<ClInclude Include="DebugInterface.h" />
|
<ClInclude Include="DebugInterface.h" />
|
||||||
<ClInclude Include="ENetUtil.h" />
|
<ClInclude Include="ENetUtil.h" />
|
||||||
|
@ -170,8 +170,8 @@
|
||||||
<ClCompile Include="CommonFuncs.cpp" />
|
<ClCompile Include="CommonFuncs.cpp" />
|
||||||
<ClCompile Include="CompatPatches.cpp" />
|
<ClCompile Include="CompatPatches.cpp" />
|
||||||
<ClCompile Include="Config\Config.cpp" />
|
<ClCompile Include="Config\Config.cpp" />
|
||||||
|
<ClCompile Include="Config\ConfigInfo.cpp" />
|
||||||
<ClCompile Include="Config\Layer.cpp" />
|
<ClCompile Include="Config\Layer.cpp" />
|
||||||
<ClCompile Include="Config\Section.cpp" />
|
|
||||||
<ClCompile Include="ENetUtil.cpp" />
|
<ClCompile Include="ENetUtil.cpp" />
|
||||||
<ClCompile Include="File.cpp" />
|
<ClCompile Include="File.cpp" />
|
||||||
<ClCompile Include="FileSearch.cpp" />
|
<ClCompile Include="FileSearch.cpp" />
|
||||||
|
|
|
@ -17,11 +17,6 @@ static std::list<ConfigChangedCallback> s_callbacks;
|
||||||
|
|
||||||
void InvokeConfigChangedCallbacks();
|
void InvokeConfigChangedCallbacks();
|
||||||
|
|
||||||
Section* GetOrCreateSection(System system, const std::string& section_name)
|
|
||||||
{
|
|
||||||
return s_layers[LayerType::Meta]->GetOrCreateSection(system, section_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Layers* GetLayers()
|
Layers* GetLayers()
|
||||||
{
|
{
|
||||||
return &s_layers;
|
return &s_layers;
|
||||||
|
@ -83,8 +78,6 @@ void Init()
|
||||||
{
|
{
|
||||||
// These layers contain temporary values
|
// These layers contain temporary values
|
||||||
ClearCurrentRunLayer();
|
ClearCurrentRunLayer();
|
||||||
// This layer always has to exist
|
|
||||||
s_layers[LayerType::Meta] = std::make_unique<RecursiveLayer>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
@ -129,26 +122,10 @@ const std::string& GetLayerName(LayerType layer)
|
||||||
{LayerType::Movie, "Movie"},
|
{LayerType::Movie, "Movie"},
|
||||||
{LayerType::CommandLine, "Command Line"},
|
{LayerType::CommandLine, "Command Line"},
|
||||||
{LayerType::CurrentRun, "Current Run"},
|
{LayerType::CurrentRun, "Current Run"},
|
||||||
{LayerType::Meta, "Top"},
|
|
||||||
};
|
};
|
||||||
return layer_to_name.at(layer);
|
return layer_to_name.at(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigLocation::operator==(const ConfigLocation& other) const
|
|
||||||
{
|
|
||||||
return std::tie(system, section, key) == std::tie(other.system, other.section, other.key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigLocation::operator!=(const ConfigLocation& other) const
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigLocation::operator<(const ConfigLocation& other) const
|
|
||||||
{
|
|
||||||
return std::tie(system, section, key) < std::tie(other.system, other.section, other.key);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerType GetActiveLayerForConfig(const ConfigLocation& config)
|
LayerType GetActiveLayerForConfig(const ConfigLocation& config)
|
||||||
{
|
{
|
||||||
for (auto layer : SEARCH_ORDER)
|
for (auto layer : SEARCH_ORDER)
|
||||||
|
@ -156,7 +133,7 @@ LayerType GetActiveLayerForConfig(const ConfigLocation& config)
|
||||||
if (!LayerExists(layer))
|
if (!LayerExists(layer))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (GetLayer(layer)->Exists(config.system, config.section, config.key))
|
if (GetLayer(layer)->Exists(config))
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,36 +9,15 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common/Config/ConfigInfo.h"
|
||||||
#include "Common/Config/Enums.h"
|
#include "Common/Config/Enums.h"
|
||||||
#include "Common/Config/Layer.h"
|
#include "Common/Config/Layer.h"
|
||||||
#include "Common/Config/Section.h"
|
|
||||||
|
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
struct ConfigLocation
|
|
||||||
{
|
|
||||||
System system;
|
|
||||||
std::string section;
|
|
||||||
std::string key;
|
|
||||||
|
|
||||||
bool operator==(const ConfigLocation& other) const;
|
|
||||||
bool operator!=(const ConfigLocation& other) const;
|
|
||||||
bool operator<(const ConfigLocation& other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ConfigInfo
|
|
||||||
{
|
|
||||||
ConfigLocation location;
|
|
||||||
T default_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
using Layers = std::map<LayerType, std::unique_ptr<Layer>>;
|
using Layers = std::map<LayerType, std::unique_ptr<Layer>>;
|
||||||
using ConfigChangedCallback = std::function<void()>;
|
using ConfigChangedCallback = std::function<void()>;
|
||||||
|
|
||||||
// Common function used for getting configuration
|
|
||||||
Section* GetOrCreateSection(System system, const std::string& section_name);
|
|
||||||
|
|
||||||
// Layer management
|
// Layer management
|
||||||
Layers* GetLayers();
|
Layers* GetLayers();
|
||||||
void AddLayer(std::unique_ptr<Layer> layer);
|
void AddLayer(std::unique_ptr<Layer> layer);
|
||||||
|
@ -66,13 +45,15 @@ LayerType GetActiveLayerForConfig(const ConfigLocation&);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Get(LayerType layer, const ConfigInfo<T>& info)
|
T Get(LayerType layer, const ConfigInfo<T>& info)
|
||||||
{
|
{
|
||||||
|
if (layer == LayerType::Meta)
|
||||||
|
return Get(info);
|
||||||
return GetLayer(layer)->Get(info);
|
return GetLayer(layer)->Get(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Get(const ConfigInfo<T>& info)
|
T Get(const ConfigInfo<T>& info)
|
||||||
{
|
{
|
||||||
return Get(LayerType::Meta, info);
|
return GetLayer(GetActiveLayerForConfig(info.location))->Get(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2016 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Common/CommonFuncs.h"
|
||||||
|
#include "Common/Config/ConfigInfo.h"
|
||||||
|
|
||||||
|
namespace Config
|
||||||
|
{
|
||||||
|
bool ConfigLocation::operator==(const ConfigLocation& other) const
|
||||||
|
{
|
||||||
|
return system == other.system && strcasecmp(section.c_str(), other.section.c_str()) == 0 &&
|
||||||
|
strcasecmp(key.c_str(), other.key.c_str()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigLocation::operator!=(const ConfigLocation& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigLocation::operator<(const ConfigLocation& other) const
|
||||||
|
{
|
||||||
|
if (system != other.system)
|
||||||
|
return system < other.system;
|
||||||
|
|
||||||
|
const int section_compare = strcasecmp(section.c_str(), other.section.c_str());
|
||||||
|
if (section_compare != 0)
|
||||||
|
return section_compare < 0;
|
||||||
|
|
||||||
|
const int key_compare = strcasecmp(key.c_str(), other.key.c_str());
|
||||||
|
return key_compare < 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2017 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common/Config/Enums.h"
|
||||||
|
|
||||||
|
namespace Config
|
||||||
|
{
|
||||||
|
struct ConfigLocation
|
||||||
|
{
|
||||||
|
System system;
|
||||||
|
std::string section;
|
||||||
|
std::string key;
|
||||||
|
|
||||||
|
bool operator==(const ConfigLocation& other) const;
|
||||||
|
bool operator!=(const ConfigLocation& other) const;
|
||||||
|
bool operator<(const ConfigLocation& other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ConfigInfo
|
||||||
|
{
|
||||||
|
ConfigLocation location;
|
||||||
|
T default_value;
|
||||||
|
};
|
||||||
|
}
|
|
@ -34,7 +34,6 @@ enum class System
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<LayerType, 7> SEARCH_ORDER{{
|
constexpr std::array<LayerType, 7> SEARCH_ORDER{{
|
||||||
// Skip the meta layer
|
|
||||||
LayerType::CurrentRun, LayerType::CommandLine, LayerType::Movie, LayerType::Netplay,
|
LayerType::CurrentRun, LayerType::CommandLine, LayerType::Movie, LayerType::Netplay,
|
||||||
LayerType::LocalGame, LayerType::GlobalGame, LayerType::Base,
|
LayerType::LocalGame, LayerType::GlobalGame, LayerType::Base,
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -8,10 +8,47 @@
|
||||||
|
|
||||||
#include "Common/Config/Config.h"
|
#include "Common/Config/Config.h"
|
||||||
#include "Common/Config/Layer.h"
|
#include "Common/Config/Layer.h"
|
||||||
#include "Common/Config/Section.h"
|
|
||||||
|
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
std::string ValueToString(u16 value)
|
||||||
|
{
|
||||||
|
return StringFromFormat("0x%04x", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(u32 value)
|
||||||
|
{
|
||||||
|
return StringFromFormat("0x%08x", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(float value)
|
||||||
|
{
|
||||||
|
return StringFromFormat("%#.9g", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(double value)
|
||||||
|
{
|
||||||
|
return StringFromFormat("%#.17g", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(int value)
|
||||||
|
{
|
||||||
|
return std::to_string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(bool value)
|
||||||
|
{
|
||||||
|
return StringFromBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueToString(const std::string& value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer)
|
ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -38,64 +75,56 @@ Layer::~Layer()
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Layer::Exists(System system, const std::string& section_name, const std::string& key)
|
bool Layer::Exists(const ConfigLocation& location) const
|
||||||
{
|
{
|
||||||
Section* section = GetSection(system, section_name);
|
const auto iter = m_map.find(location);
|
||||||
if (!section)
|
return iter != m_map.end() && iter->second.has_value();
|
||||||
return false;
|
|
||||||
return section->Exists(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Layer::DeleteKey(System system, const std::string& section_name, const std::string& key)
|
bool Layer::DeleteKey(const ConfigLocation& location)
|
||||||
{
|
{
|
||||||
Section* section = GetSection(system, section_name);
|
m_is_dirty = true;
|
||||||
if (!section)
|
bool had_value = m_map[location].has_value();
|
||||||
return false;
|
m_map[location].reset();
|
||||||
return section->Delete(key);
|
return had_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Section* Layer::GetSection(System system, const std::string& section_name)
|
void Layer::DeleteAllKeys()
|
||||||
{
|
{
|
||||||
for (auto& section : m_sections[system])
|
m_is_dirty = true;
|
||||||
if (!strcasecmp(section->m_name.c_str(), section_name.c_str()))
|
for (auto& pair : m_map)
|
||||||
return section.get();
|
{
|
||||||
return nullptr;
|
pair.second.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section* Layer::GetOrCreateSection(System system, const std::string& section_name)
|
Section Layer::GetSection(System system, const std::string& section)
|
||||||
{
|
{
|
||||||
Section* section = GetSection(system, section_name);
|
return Section{m_map.lower_bound(ConfigLocation{system, section, ""}),
|
||||||
if (!section)
|
m_map.lower_bound(ConfigLocation{system, section + '\001', ""})};
|
||||||
{
|
}
|
||||||
if (m_layer == LayerType::Meta)
|
|
||||||
{
|
ConstSection Layer::GetSection(System system, const std::string& section) const
|
||||||
m_sections[system].emplace_back(
|
{
|
||||||
std::make_unique<RecursiveSection>(m_layer, system, section_name));
|
return ConstSection{m_map.lower_bound(ConfigLocation{system, section, ""}),
|
||||||
}
|
m_map.lower_bound(ConfigLocation{system, section + '\001', ""})};
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sections[system].emplace_back(std::make_unique<Section>(m_layer, system, section_name));
|
|
||||||
}
|
|
||||||
section = m_sections[system].back().get();
|
|
||||||
}
|
|
||||||
return section;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer::Load()
|
void Layer::Load()
|
||||||
{
|
{
|
||||||
if (m_loader)
|
if (m_loader)
|
||||||
m_loader->Load(this);
|
m_loader->Load(this);
|
||||||
ClearDirty();
|
m_is_dirty = false;
|
||||||
InvokeConfigChangedCallbacks();
|
InvokeConfigChangedCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer::Save()
|
void Layer::Save()
|
||||||
{
|
{
|
||||||
if (!m_loader || !IsDirty())
|
if (!m_loader || !m_is_dirty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_loader->Save(this);
|
m_loader->Save(this);
|
||||||
ClearDirty();
|
m_is_dirty = false;
|
||||||
InvokeConfigChangedCallbacks();
|
InvokeConfigChangedCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,44 +135,6 @@ LayerType Layer::GetLayer() const
|
||||||
|
|
||||||
const LayerMap& Layer::GetLayerMap() const
|
const LayerMap& Layer::GetLayerMap() const
|
||||||
{
|
{
|
||||||
return m_sections;
|
return m_map;
|
||||||
}
|
|
||||||
|
|
||||||
bool Layer::IsDirty() const
|
|
||||||
{
|
|
||||||
return std::any_of(m_sections.begin(), m_sections.end(), [](const auto& system) {
|
|
||||||
return std::any_of(system.second.begin(), system.second.end(),
|
|
||||||
[](const auto& section) { return section->IsDirty(); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::ClearDirty()
|
|
||||||
{
|
|
||||||
std::for_each(m_sections.begin(), m_sections.end(), [](auto& system) {
|
|
||||||
std::for_each(system.second.begin(), system.second.end(),
|
|
||||||
[](auto& section) { section->ClearDirty(); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveLayer::RecursiveLayer() : Layer(LayerType::Meta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Section* RecursiveLayer::GetSection(System system, const std::string& section_name)
|
|
||||||
{
|
|
||||||
// Always queries backwards recursively, so it doesn't matter if it exists or not on this layer
|
|
||||||
return GetOrCreateSection(system, section_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Section* RecursiveLayer::GetOrCreateSection(System system, const std::string& section_name)
|
|
||||||
{
|
|
||||||
Section* section = Layer::GetSection(system, section_name);
|
|
||||||
if (!section)
|
|
||||||
{
|
|
||||||
m_sections[system].emplace_back(
|
|
||||||
std::make_unique<RecursiveSection>(m_layer, system, section_name));
|
|
||||||
section = m_sections[system].back().get();
|
|
||||||
}
|
|
||||||
return section;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,47 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common/Config/ConfigInfo.h"
|
||||||
#include "Common/Config/Enums.h"
|
#include "Common/Config/Enums.h"
|
||||||
#include "Common/Config/Section.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
std::string ValueToString(u16 value);
|
||||||
|
std::string ValueToString(u32 value);
|
||||||
|
std::string ValueToString(float value);
|
||||||
|
std::string ValueToString(double value);
|
||||||
|
std::string ValueToString(int value);
|
||||||
|
std::string ValueToString(bool value);
|
||||||
|
std::string ValueToString(const std::string& value);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::optional<T> TryParse(const std::string& str_value)
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
if (!::TryParse(str_value, &value))
|
||||||
|
return std::nullopt;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline std::optional<std::string> TryParse(const std::string& str_value)
|
||||||
|
{
|
||||||
|
return str_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ConfigInfo;
|
struct ConfigInfo;
|
||||||
|
|
||||||
using LayerMap = std::map<System, std::vector<std::unique_ptr<Section>>>;
|
class Layer;
|
||||||
|
using LayerMap = std::map<ConfigLocation, std::optional<std::string>>;
|
||||||
|
|
||||||
class ConfigLayerLoader
|
class ConfigLayerLoader
|
||||||
{
|
{
|
||||||
|
@ -33,6 +62,30 @@ private:
|
||||||
const LayerType m_layer;
|
const LayerType m_layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Section
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = LayerMap::iterator;
|
||||||
|
Section(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {}
|
||||||
|
iterator begin() const { return m_begin; }
|
||||||
|
iterator end() const { return m_end; }
|
||||||
|
private:
|
||||||
|
iterator m_begin;
|
||||||
|
iterator m_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConstSection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = LayerMap::const_iterator;
|
||||||
|
ConstSection(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {}
|
||||||
|
iterator begin() const { return m_begin; }
|
||||||
|
iterator end() const { return m_end; }
|
||||||
|
private:
|
||||||
|
iterator m_begin;
|
||||||
|
iterator m_end;
|
||||||
|
};
|
||||||
|
|
||||||
class Layer
|
class Layer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,34 +94,45 @@ public:
|
||||||
virtual ~Layer();
|
virtual ~Layer();
|
||||||
|
|
||||||
// Convenience functions
|
// Convenience functions
|
||||||
bool Exists(System system, const std::string& section_name, const std::string& key);
|
bool Exists(const ConfigLocation& location) const;
|
||||||
bool DeleteKey(System system, const std::string& section_name, const std::string& key);
|
bool DeleteKey(const ConfigLocation& location);
|
||||||
template <typename T>
|
void DeleteAllKeys();
|
||||||
bool GetIfExists(System system, const std::string& section_name, const std::string& key, T* value)
|
|
||||||
{
|
|
||||||
if (Exists(system, section_name, key))
|
|
||||||
return GetOrCreateSection(system, section_name)->Get(key, value);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Section* GetSection(System system, const std::string& section_name);
|
|
||||||
virtual Section* GetOrCreateSection(System system, const std::string& section_name);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Get(const ConfigInfo<T>& config_info)
|
T Get(const ConfigInfo<T>& config_info)
|
||||||
{
|
{
|
||||||
return GetOrCreateSection(config_info.location.system, config_info.location.section)
|
return Get<T>(config_info.location).value_or(config_info.default_value);
|
||||||
->template Get<T>(config_info.location.key, config_info.default_value);
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::optional<T> Get(const ConfigLocation& location)
|
||||||
|
{
|
||||||
|
const std::optional<std::string>& str_value = m_map[location];
|
||||||
|
if (!str_value)
|
||||||
|
return std::nullopt;
|
||||||
|
return detail::TryParse<T>(*str_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Set(const ConfigInfo<T>& config_info, const T& value)
|
void Set(const ConfigInfo<T>& config_info, const T& value)
|
||||||
{
|
{
|
||||||
GetOrCreateSection(config_info.location.system, config_info.location.section)
|
Set<T>(config_info.location, value);
|
||||||
->Set(config_info.location.key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Set(const ConfigLocation& location, const T& value)
|
||||||
|
{
|
||||||
|
const std::string new_value = detail::ValueToString(value);
|
||||||
|
std::optional<std::string>& current_value = m_map[location];
|
||||||
|
if (current_value == new_value)
|
||||||
|
return;
|
||||||
|
m_is_dirty = true;
|
||||||
|
current_value = new_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Section GetSection(System system, const std::string& section);
|
||||||
|
ConstSection GetSection(System system, const std::string& section) const;
|
||||||
|
|
||||||
// Explicit load and save of layers
|
// Explicit load and save of layers
|
||||||
void Load();
|
void Load();
|
||||||
void Save();
|
void Save();
|
||||||
|
@ -77,19 +141,9 @@ public:
|
||||||
const LayerMap& GetLayerMap() const;
|
const LayerMap& GetLayerMap() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool IsDirty() const;
|
bool m_is_dirty = false;
|
||||||
void ClearDirty();
|
LayerMap m_map;
|
||||||
|
|
||||||
LayerMap m_sections;
|
|
||||||
const LayerType m_layer;
|
const LayerType m_layer;
|
||||||
std::unique_ptr<ConfigLayerLoader> m_loader;
|
std::unique_ptr<ConfigLayerLoader> m_loader;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecursiveLayer final : public Layer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RecursiveLayer();
|
|
||||||
Section* GetSection(System system, const std::string& section_name) override;
|
|
||||||
Section* GetOrCreateSection(System system, const std::string& section_name) override;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,296 +0,0 @@
|
||||||
// Copyright 2017 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
|
||||||
#include "Common/Config/Config.h"
|
|
||||||
#include "Common/Config/Layer.h"
|
|
||||||
#include "Common/Config/Section.h"
|
|
||||||
#include "Common/StringUtil.h"
|
|
||||||
|
|
||||||
namespace Config
|
|
||||||
{
|
|
||||||
const std::string& Section::NULL_STRING = "";
|
|
||||||
|
|
||||||
Section::Section(LayerType layer, System system, const std::string& name)
|
|
||||||
: m_layer(layer), m_system(system), m_name(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Exists(const std::string& key) const
|
|
||||||
{
|
|
||||||
return m_values.find(key) != m_values.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Delete(const std::string& key)
|
|
||||||
{
|
|
||||||
auto it = m_values.find(key);
|
|
||||||
if (it == m_values.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_values.erase(it);
|
|
||||||
|
|
||||||
m_deleted_keys.push_back(key);
|
|
||||||
m_dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, const std::string& value)
|
|
||||||
{
|
|
||||||
auto it = m_values.find(key);
|
|
||||||
if (it != m_values.end() && it->second != value)
|
|
||||||
{
|
|
||||||
it->second = value;
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
else if (it == m_values.end())
|
|
||||||
{
|
|
||||||
m_values[key] = value;
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, u16 newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, StringFromFormat("0x%04x", newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, u32 newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, StringFromFormat("0x%08x", newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, float newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, StringFromFormat("%#.9g", newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, double newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, StringFromFormat("%#.17g", newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, int newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, std::to_string(newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, bool newValue)
|
|
||||||
{
|
|
||||||
Section::Set(key, StringFromBool(newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::Set(const std::string& key, const std::string& newValue,
|
|
||||||
const std::string& defaultValue)
|
|
||||||
{
|
|
||||||
if (newValue != defaultValue)
|
|
||||||
Set(key, newValue);
|
|
||||||
else
|
|
||||||
Delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::SetLines(const std::vector<std::string>& lines)
|
|
||||||
{
|
|
||||||
m_lines = lines;
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, std::string* value,
|
|
||||||
const std::string& default_value) const
|
|
||||||
{
|
|
||||||
const auto& it = m_values.find(key);
|
|
||||||
if (it != m_values.end())
|
|
||||||
{
|
|
||||||
*value = it->second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (&default_value != &NULL_STRING)
|
|
||||||
{
|
|
||||||
*value = default_value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, int* value, int defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, u16* value, u16 defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, u32* value, u32 defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, bool* value, bool defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, float* value, float defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::Get(const std::string& key, double* value, double defaultValue) const
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
bool retval = Get(key, &temp);
|
|
||||||
|
|
||||||
if (retval && TryParse(temp, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
*value = defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a list of all lines in a section
|
|
||||||
bool Section::GetLines(std::vector<std::string>* lines, const bool remove_comments) const
|
|
||||||
{
|
|
||||||
lines->clear();
|
|
||||||
|
|
||||||
for (std::string line : m_lines)
|
|
||||||
{
|
|
||||||
line = StripSpaces(line);
|
|
||||||
|
|
||||||
if (remove_comments)
|
|
||||||
{
|
|
||||||
size_t commentPos = line.find('#');
|
|
||||||
if (commentPos == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commentPos != std::string::npos)
|
|
||||||
{
|
|
||||||
line = StripSpaces(line.substr(0, commentPos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lines->push_back(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::HasLines() const
|
|
||||||
{
|
|
||||||
return !m_lines.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& Section::GetName() const
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SectionValueMap& Section::GetValues() const
|
|
||||||
{
|
|
||||||
return m_values;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& Section::GetDeletedKeys() const
|
|
||||||
{
|
|
||||||
return m_deleted_keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Section::IsDirty() const
|
|
||||||
{
|
|
||||||
return m_dirty;
|
|
||||||
}
|
|
||||||
void Section::ClearDirty()
|
|
||||||
{
|
|
||||||
m_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveSection::RecursiveSection(LayerType layer, System system, const std::string& name)
|
|
||||||
: Section(layer, system, name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RecursiveSection::Exists(const std::string& key) const
|
|
||||||
{
|
|
||||||
auto layers_it = Config::GetLayers()->find(LayerType::Meta);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const Section* layer_section = layers_it->second->GetSection(m_system, m_name);
|
|
||||||
if (layer_section && layer_section->Exists(key))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} while (--layers_it != Config::GetLayers()->end());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RecursiveSection::Get(const std::string& key, std::string* value,
|
|
||||||
const std::string& default_value) const
|
|
||||||
{
|
|
||||||
for (auto layer_id : SEARCH_ORDER)
|
|
||||||
{
|
|
||||||
auto layers_it = Config::GetLayers()->find(layer_id);
|
|
||||||
if (layers_it == Config::GetLayers()->end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const Section* layer_section = layers_it->second->GetSection(m_system, m_name);
|
|
||||||
if (layer_section && layer_section->Exists(key))
|
|
||||||
{
|
|
||||||
return layer_section->Get(key, value, default_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Section::Get(key, value, default_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RecursiveSection::Set(const std::string& key, const std::string& value)
|
|
||||||
{
|
|
||||||
// The RecursiveSection can't set since it is used to recursively get values from the layer
|
|
||||||
// map.
|
|
||||||
// It is only a part of the meta layer, and the meta layer isn't allowed to set any values.
|
|
||||||
_assert_msg_(COMMON, false, "Don't try to set values here!");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
// Copyright 2017 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// XXX: Purely for case insensitive compare
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "Common/Config/Enums.h"
|
|
||||||
#include "Common/IniFile.h"
|
|
||||||
|
|
||||||
namespace Config
|
|
||||||
{
|
|
||||||
class Layer;
|
|
||||||
class ConfigLayerLoader;
|
|
||||||
|
|
||||||
using SectionValueMap = std::map<std::string, std::string, CaseInsensitiveStringCompare>;
|
|
||||||
|
|
||||||
class Section
|
|
||||||
{
|
|
||||||
friend Layer;
|
|
||||||
friend ConfigLayerLoader;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Section(LayerType layer, System system, const std::string& name);
|
|
||||||
virtual ~Section() = default;
|
|
||||||
|
|
||||||
virtual bool Exists(const std::string& key) const;
|
|
||||||
bool Delete(const std::string& key);
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
virtual void Set(const std::string& key, const std::string& value);
|
|
||||||
|
|
||||||
void Set(const std::string& key, u16 newValue);
|
|
||||||
void Set(const std::string& key, u32 newValue);
|
|
||||||
void Set(const std::string& key, float newValue);
|
|
||||||
void Set(const std::string& key, double newValue);
|
|
||||||
void Set(const std::string& key, int newValue);
|
|
||||||
void Set(const std::string& key, bool newValue);
|
|
||||||
|
|
||||||
// Setters with default values
|
|
||||||
void Set(const std::string& key, const std::string& newValue, const std::string& defaultValue);
|
|
||||||
template <typename T>
|
|
||||||
void Set(const std::string& key, T newValue, const T defaultValue)
|
|
||||||
{
|
|
||||||
if (newValue != defaultValue)
|
|
||||||
Set(key, newValue);
|
|
||||||
else
|
|
||||||
Delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
virtual bool Get(const std::string& key, std::string* value,
|
|
||||||
const std::string& default_value = NULL_STRING) const;
|
|
||||||
|
|
||||||
bool Get(const std::string& key, int* value, int defaultValue = 0) const;
|
|
||||||
bool Get(const std::string& key, u16* value, u16 defaultValue = 0) const;
|
|
||||||
bool Get(const std::string& key, u32* value, u32 defaultValue = 0) const;
|
|
||||||
bool Get(const std::string& key, bool* value, bool defaultValue = false) const;
|
|
||||||
bool Get(const std::string& key, float* value, float defaultValue = 0.0f) const;
|
|
||||||
bool Get(const std::string& key, double* value, double defaultValue = 0.0) const;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T Get(const std::string& key, const T& default_value) const
|
|
||||||
{
|
|
||||||
T value;
|
|
||||||
Get(key, &value, default_value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section chunk
|
|
||||||
void SetLines(const std::vector<std::string>& lines);
|
|
||||||
// XXX: Add to recursive layer
|
|
||||||
virtual bool GetLines(std::vector<std::string>* lines, const bool remove_comments = true) const;
|
|
||||||
virtual bool HasLines() const;
|
|
||||||
const std::string& GetName() const;
|
|
||||||
const SectionValueMap& GetValues() const;
|
|
||||||
const std::vector<std::string>& GetDeletedKeys() const;
|
|
||||||
bool IsDirty() const;
|
|
||||||
void ClearDirty();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool m_dirty = false;
|
|
||||||
|
|
||||||
LayerType m_layer;
|
|
||||||
System m_system;
|
|
||||||
const std::string m_name;
|
|
||||||
static const std::string& NULL_STRING;
|
|
||||||
|
|
||||||
SectionValueMap m_values;
|
|
||||||
std::vector<std::string> m_deleted_keys;
|
|
||||||
|
|
||||||
std::vector<std::string> m_lines;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Only to be used with the meta-layer
|
|
||||||
class RecursiveSection final : public Section
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RecursiveSection(LayerType layer, System system, const std::string& name);
|
|
||||||
|
|
||||||
bool Exists(const std::string& key) const override;
|
|
||||||
|
|
||||||
bool Get(const std::string& key, std::string* value,
|
|
||||||
const std::string& default_value = NULL_STRING) const override;
|
|
||||||
|
|
||||||
void Set(const std::string& key, const std::string& value) override;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -376,7 +376,7 @@ bool BootCore(std::unique_ptr<BootParameters> boot)
|
||||||
|
|
||||||
// Ensure any new settings are written to the SYSCONF
|
// Ensure any new settings are written to the SYSCONF
|
||||||
if (StartUp.bWii)
|
if (StartUp.bWii)
|
||||||
ConfigLoaders::SaveToSYSCONF(Config::GetLayer(Config::LayerType::Meta));
|
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta);
|
||||||
|
|
||||||
const bool load_ipl = !StartUp.bWii && !StartUp.bHLE_BS2 &&
|
const bool load_ipl = !StartUp.bWii && !StartUp.bHLE_BS2 &&
|
||||||
std::holds_alternative<BootParameters::Disc>(boot->parameters);
|
std::holds_alternative<BootParameters::Disc>(boot->parameters);
|
||||||
|
|
|
@ -61,6 +61,7 @@ ConfigInfo<bool> GetInfoForSimulateKonga(u32 channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfigInfo<bool> MAIN_WII_SD_CARD{{System::Main, "Core", "WiiSDCard"}, false};
|
const ConfigInfo<bool> MAIN_WII_SD_CARD{{System::Main, "Core", "WiiSDCard"}, false};
|
||||||
|
const ConfigInfo<bool> MAIN_WII_SD_CARD_WRITABLE{{System::Main, "Core", "WiiSDCardWritable"}, true};
|
||||||
const ConfigInfo<bool> MAIN_WII_KEYBOARD{{System::Main, "Core", "WiiKeyboard"}, false};
|
const ConfigInfo<bool> MAIN_WII_KEYBOARD{{System::Main, "Core", "WiiKeyboard"}, false};
|
||||||
const ConfigInfo<bool> MAIN_WIIMOTE_CONTINUOUS_SCANNING{
|
const ConfigInfo<bool> MAIN_WIIMOTE_CONTINUOUS_SCANNING{
|
||||||
{System::Main, "Core", "WiimoteContinuousScanning"}, false};
|
{System::Main, "Core", "WiimoteContinuousScanning"}, false};
|
||||||
|
|
|
@ -40,6 +40,7 @@ ConfigInfo<u32> GetInfoForSIDevice(u32 channel);
|
||||||
ConfigInfo<bool> GetInfoForAdapterRumble(u32 channel);
|
ConfigInfo<bool> GetInfoForAdapterRumble(u32 channel);
|
||||||
ConfigInfo<bool> GetInfoForSimulateKonga(u32 channel);
|
ConfigInfo<bool> GetInfoForSimulateKonga(u32 channel);
|
||||||
extern const ConfigInfo<bool> MAIN_WII_SD_CARD;
|
extern const ConfigInfo<bool> MAIN_WII_SD_CARD;
|
||||||
|
extern const ConfigInfo<bool> MAIN_WII_SD_CARD_WRITABLE;
|
||||||
extern const ConfigInfo<bool> MAIN_WII_KEYBOARD;
|
extern const ConfigInfo<bool> MAIN_WII_KEYBOARD;
|
||||||
extern const ConfigInfo<bool> MAIN_WIIMOTE_CONTINUOUS_SCANNING;
|
extern const ConfigInfo<bool> MAIN_WIIMOTE_CONTINUOUS_SCANNING;
|
||||||
extern const ConfigInfo<bool> MAIN_WIIMOTE_ENABLE_SPEAKER;
|
extern const ConfigInfo<bool> MAIN_WIIMOTE_ENABLE_SPEAKER;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
namespace ConfigLoaders
|
namespace ConfigLoaders
|
||||||
{
|
{
|
||||||
void SaveToSYSCONF(Config::Layer* layer)
|
void SaveToSYSCONF(Config::LayerType layer)
|
||||||
{
|
{
|
||||||
if (Core::IsRunning())
|
if (Core::IsRunning())
|
||||||
return;
|
return;
|
||||||
|
@ -40,9 +40,9 @@ void SaveToSYSCONF(Config::Layer* layer)
|
||||||
const std::string key = info.location.section + "." + info.location.key;
|
const std::string key = info.location.section + "." + info.location.key;
|
||||||
|
|
||||||
if (setting.type == SysConf::Entry::Type::Long)
|
if (setting.type == SysConf::Entry::Type::Long)
|
||||||
sysconf.SetData<u32>(key, setting.type, layer->Get(info));
|
sysconf.SetData<u32>(key, setting.type, Config::Get(layer, info));
|
||||||
else if (setting.type == SysConf::Entry::Type::Byte)
|
else if (setting.type == SysConf::Entry::Type::Byte)
|
||||||
sysconf.SetData<u8>(key, setting.type, static_cast<u8>(layer->Get(info)));
|
sysconf.SetData<u8>(key, setting.type, static_cast<u8>(Config::Get(layer, info)));
|
||||||
},
|
},
|
||||||
setting.config_info);
|
setting.config_info);
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,9 @@ class BaseConfigLayerLoader final : public Config::ConfigLayerLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BaseConfigLayerLoader() : ConfigLayerLoader(Config::LayerType::Base) {}
|
BaseConfigLayerLoader() : ConfigLayerLoader(Config::LayerType::Base) {}
|
||||||
void Load(Config::Layer* config_layer) override
|
void Load(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
LoadFromSYSCONF(config_layer);
|
LoadFromSYSCONF(layer);
|
||||||
for (const auto& system : system_to_ini)
|
for (const auto& system : system_to_ini)
|
||||||
{
|
{
|
||||||
IniFile ini;
|
IniFile ini;
|
||||||
|
@ -89,55 +89,62 @@ public:
|
||||||
for (const auto& section : system_sections)
|
for (const auto& section : system_sections)
|
||||||
{
|
{
|
||||||
const std::string section_name = section.GetName();
|
const std::string section_name = section.GetName();
|
||||||
Config::Section* config_section =
|
|
||||||
config_layer->GetOrCreateSection(system.first, section_name);
|
|
||||||
const IniFile::Section::SectionMap& section_map = section.GetValues();
|
const IniFile::Section::SectionMap& section_map = section.GetValues();
|
||||||
|
|
||||||
for (const auto& value : section_map)
|
for (const auto& value : section_map)
|
||||||
config_section->Set(value.first, value.second);
|
{
|
||||||
|
const Config::ConfigLocation location{system.first, section_name, value.first};
|
||||||
|
layer->Set(location, value.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Save(Config::Layer* config_layer) override
|
void Save(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
const Config::LayerMap& sections = config_layer->GetLayerMap();
|
SaveToSYSCONF(layer->GetLayer());
|
||||||
for (const auto& system : sections)
|
|
||||||
|
std::map<Config::System, IniFile> inis;
|
||||||
|
|
||||||
|
for (const auto& system : system_to_ini)
|
||||||
{
|
{
|
||||||
if (system.first == Config::System::SYSCONF)
|
inis[system.first].Load(File::GetUserPath(system.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& config : layer->GetLayerMap())
|
||||||
{
|
{
|
||||||
SaveToSYSCONF(config_layer);
|
const Config::ConfigLocation& location = config.first;
|
||||||
|
const std::optional<std::string>& value = config.second;
|
||||||
|
|
||||||
|
// Done by SaveToSYSCONF
|
||||||
|
if (location.system == Config::System::SYSCONF)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
auto mapping = system_to_ini.find(system.first);
|
auto ini = inis.find(location.system);
|
||||||
if (mapping == system_to_ini.end())
|
if (ini == inis.end())
|
||||||
{
|
{
|
||||||
ERROR_LOG(COMMON, "Config can't map system '%s' to an INI file!",
|
ERROR_LOG(COMMON, "Config can't map system '%s' to an INI file!",
|
||||||
Config::GetSystemName(system.first).c_str());
|
Config::GetSystemName(location.system).c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
IniFile ini;
|
if (!IsSettingSaveable(location))
|
||||||
ini.Load(File::GetUserPath(mapping->second));
|
|
||||||
|
|
||||||
for (const auto& section : system.second)
|
|
||||||
{
|
|
||||||
const std::string section_name = section->GetName();
|
|
||||||
const Config::SectionValueMap& section_values = section->GetValues();
|
|
||||||
|
|
||||||
IniFile::Section* ini_section = ini.GetOrCreateSection(section_name);
|
|
||||||
|
|
||||||
for (const auto& value : section_values)
|
|
||||||
{
|
|
||||||
if (!IsSettingSaveable({system.first, section->GetName(), value.first}))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ini_section->Set(value.first, value.second);
|
if (value)
|
||||||
|
{
|
||||||
|
IniFile::Section* ini_section = ini->second.GetOrCreateSection(location.section);
|
||||||
|
ini_section->Set(location.key, *value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ini->second.DeleteKey(location.section, location.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ini.Save(File::GetUserPath(mapping->second));
|
for (const auto& system : system_to_ini)
|
||||||
|
{
|
||||||
|
inis[system.first].Save(File::GetUserPath(system.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,13 +160,10 @@ private:
|
||||||
std::visit(
|
std::visit(
|
||||||
[&](auto& info) {
|
[&](auto& info) {
|
||||||
const std::string key = info.location.section + "." + info.location.key;
|
const std::string key = info.location.section + "." + info.location.key;
|
||||||
auto* section =
|
|
||||||
layer->GetOrCreateSection(Config::System::SYSCONF, info.location.section);
|
|
||||||
|
|
||||||
if (setting.type == SysConf::Entry::Type::Long)
|
if (setting.type == SysConf::Entry::Type::Long)
|
||||||
section->Set(info.location.key, sysconf.GetData<u32>(key, info.default_value));
|
layer->Set(info.location, sysconf.GetData<u32>(key, info.default_value));
|
||||||
else if (setting.type == SysConf::Entry::Type::Byte)
|
else if (setting.type == SysConf::Entry::Type::Byte)
|
||||||
section->Set(info.location.key, sysconf.GetData<u8>(key, info.default_value));
|
layer->Set(info.location, sysconf.GetData<u8>(key, info.default_value));
|
||||||
},
|
},
|
||||||
setting.config_info);
|
setting.config_info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
class ConfigLayerLoader;
|
class ConfigLayerLoader;
|
||||||
class Layer;
|
enum class LayerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigLoaders
|
namespace ConfigLoaders
|
||||||
{
|
{
|
||||||
void SaveToSYSCONF(Config::Layer* layer);
|
void SaveToSYSCONF(Config::LayerType layer);
|
||||||
std::unique_ptr<Config::ConfigLayerLoader> GenerateBaseConfigLoader();
|
std::unique_ptr<Config::ConfigLayerLoader> GenerateBaseConfigLoader();
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,10 +199,10 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Load(Config::Layer* config_layer) override
|
void Load(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
IniFile ini;
|
IniFile ini;
|
||||||
if (config_layer->GetLayer() == Config::LayerType::GlobalGame)
|
if (layer->GetLayer() == Config::LayerType::GlobalGame)
|
||||||
{
|
{
|
||||||
for (const std::string& filename : GetGameIniFilenames(m_id, m_revision))
|
for (const std::string& filename : GetGameIniFilenames(m_id, m_revision))
|
||||||
ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + filename, true);
|
ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + filename, true);
|
||||||
|
@ -217,16 +217,16 @@ public:
|
||||||
|
|
||||||
for (const auto& section : system_sections)
|
for (const auto& section : system_sections)
|
||||||
{
|
{
|
||||||
LoadFromSystemSection(config_layer, section);
|
LoadFromSystemSection(layer, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadControllerConfig(config_layer);
|
LoadControllerConfig(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Save(Config::Layer* config_layer) override;
|
void Save(Config::Layer* layer) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadControllerConfig(Config::Layer* config_layer) const
|
void LoadControllerConfig(Config::Layer* layer) const
|
||||||
{
|
{
|
||||||
// Game INIs can have controller profiles embedded in to them
|
// Game INIs can have controller profiles embedded in to them
|
||||||
static const std::array<char, 4> nums = {{'1', '2', '3', '4'}};
|
static const std::array<char, 4> nums = {{'1', '2', '3', '4'}};
|
||||||
|
@ -244,82 +244,53 @@ private:
|
||||||
std::string type = std::get<0>(use_data);
|
std::string type = std::get<0>(use_data);
|
||||||
std::string path = "Profiles/" + std::get<1>(use_data) + "/";
|
std::string path = "Profiles/" + std::get<1>(use_data) + "/";
|
||||||
|
|
||||||
Config::Section* control_section =
|
const auto control_section = [&](std::string key) {
|
||||||
config_layer->GetOrCreateSection(std::get<2>(use_data), "Controls");
|
return Config::ConfigLocation{std::get<2>(use_data), "Controls", key};
|
||||||
|
};
|
||||||
|
|
||||||
for (const char num : nums)
|
for (const char num : nums)
|
||||||
{
|
{
|
||||||
bool use_profile = false;
|
if (auto profile = layer->Get<std::string>(control_section(type + "Profile" + num)))
|
||||||
std::string profile;
|
|
||||||
if (control_section->Exists(type + "Profile" + num))
|
|
||||||
{
|
{
|
||||||
if (control_section->Get(type + "Profile" + num, &profile))
|
std::string ini_path = File::GetUserPath(D_CONFIG_IDX) + path + *profile + ".ini";
|
||||||
{
|
if (!File::Exists(ini_path))
|
||||||
if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile + ".ini"))
|
|
||||||
{
|
|
||||||
use_profile = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// TODO: PanicAlert shouldn't be used for this.
|
// TODO: PanicAlert shouldn't be used for this.
|
||||||
PanicAlertT("Selected controller profile does not exist");
|
PanicAlertT("Selected controller profile does not exist");
|
||||||
}
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_profile)
|
|
||||||
{
|
|
||||||
IniFile profile_ini;
|
IniFile profile_ini;
|
||||||
profile_ini.Load(File::GetUserPath(D_CONFIG_IDX) + path + profile + ".ini");
|
profile_ini.Load(ini_path);
|
||||||
|
|
||||||
const IniFile::Section* ini_section = profile_ini.GetOrCreateSection("Profile");
|
const IniFile::Section* ini_section = profile_ini.GetOrCreateSection("Profile");
|
||||||
const IniFile::Section::SectionMap& section_map = ini_section->GetValues();
|
const IniFile::Section::SectionMap& section_map = ini_section->GetValues();
|
||||||
for (const auto& value : section_map)
|
for (const auto& value : section_map)
|
||||||
{
|
{
|
||||||
Config::Section* section = config_layer->GetOrCreateSection(
|
Config::ConfigLocation location{std::get<2>(use_data), std::get<1>(use_data) + num,
|
||||||
std::get<2>(use_data), std::get<1>(use_data) + num);
|
value.first};
|
||||||
section->Set(value.first, value.second);
|
layer->Set(location, value.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadFromSystemSection(Config::Layer* config_layer, const IniFile::Section& section) const
|
void LoadFromSystemSection(Config::Layer* layer, const IniFile::Section& section) const
|
||||||
{
|
{
|
||||||
const std::string section_name = section.GetName();
|
const std::string section_name = section.GetName();
|
||||||
if (section.HasLines())
|
|
||||||
{
|
|
||||||
// Trash INI File chunks
|
|
||||||
std::vector<std::string> chunk;
|
|
||||||
section.GetLines(&chunk, true);
|
|
||||||
|
|
||||||
if (chunk.size())
|
|
||||||
{
|
|
||||||
const auto mapped_config = MapINIToRealLocation(section_name, "");
|
|
||||||
|
|
||||||
if (mapped_config.section.empty() && mapped_config.key.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto* config_section =
|
|
||||||
config_layer->GetOrCreateSection(mapped_config.system, mapped_config.section);
|
|
||||||
config_section->SetLines(chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regular key,value pairs
|
// Regular key,value pairs
|
||||||
const IniFile::Section::SectionMap& section_map = section.GetValues();
|
const IniFile::Section::SectionMap& section_map = section.GetValues();
|
||||||
|
|
||||||
for (const auto& value : section_map)
|
for (const auto& value : section_map)
|
||||||
{
|
{
|
||||||
const auto mapped_config = MapINIToRealLocation(section_name, value.first);
|
const auto location = MapINIToRealLocation(section_name, value.first);
|
||||||
|
|
||||||
if (mapped_config.section.empty() && mapped_config.key.empty())
|
if (location.section.empty() && location.key.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto* config_section =
|
layer->Set(location, value.second);
|
||||||
config_layer->GetOrCreateSection(mapped_config.system, mapped_config.section);
|
|
||||||
config_section->Set(mapped_config.key, value.second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,32 +298,35 @@ private:
|
||||||
const u16 m_revision;
|
const u16 m_revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
void INIGameConfigLayerLoader::Save(Config::Layer* config_layer)
|
void INIGameConfigLayerLoader::Save(Config::Layer* layer)
|
||||||
{
|
{
|
||||||
if (config_layer->GetLayer() != Config::LayerType::LocalGame)
|
if (layer->GetLayer() != Config::LayerType::LocalGame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IniFile ini;
|
IniFile ini;
|
||||||
for (const std::string& file_name : GetGameIniFilenames(m_id, m_revision))
|
for (const std::string& file_name : GetGameIniFilenames(m_id, m_revision))
|
||||||
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + file_name, true);
|
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + file_name, true);
|
||||||
|
|
||||||
for (const auto& system : config_layer->GetLayerMap())
|
for (const auto& config : layer->GetLayerMap())
|
||||||
{
|
{
|
||||||
for (const auto& section : system.second)
|
const Config::ConfigLocation& location = config.first;
|
||||||
{
|
const std::optional<std::string>& value = config.second;
|
||||||
for (const auto& value : section->GetValues())
|
|
||||||
{
|
if (!IsSettingSaveable(location))
|
||||||
if (!IsSettingSaveable({system.first, section->GetName(), value.first}))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto ini_location =
|
const auto ini_location = GetINILocationFromConfig(location);
|
||||||
GetINILocationFromConfig({system.first, section->GetName(), value.first});
|
|
||||||
if (ini_location.first.empty() && ini_location.second.empty())
|
if (ini_location.first.empty() && ini_location.second.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
IniFile::Section* ini_section = ini.GetOrCreateSection(ini_location.first);
|
IniFile::Section* ini_section = ini.GetOrCreateSection(ini_location.first);
|
||||||
ini_section->Set(ini_location.second, value.second);
|
ini_section->Set(ini_location.second, *value);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ini.DeleteKey(ini_location.first, ini_location.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,27 +46,27 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
|
||||||
config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges);
|
config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveToDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
|
void SaveToDTM(Movie::DTMHeader* dtm)
|
||||||
{
|
{
|
||||||
dtm->bDualCore = config_layer->Get(Config::MAIN_CPU_THREAD);
|
dtm->bDualCore = Config::Get(Config::MAIN_CPU_THREAD);
|
||||||
dtm->bDSPHLE = config_layer->Get(Config::MAIN_DSP_HLE);
|
dtm->bDSPHLE = Config::Get(Config::MAIN_DSP_HLE);
|
||||||
dtm->bFastDiscSpeed = config_layer->Get(Config::MAIN_FAST_DISC_SPEED);
|
dtm->bFastDiscSpeed = Config::Get(Config::MAIN_FAST_DISC_SPEED);
|
||||||
dtm->CPUCore = config_layer->Get(Config::MAIN_CPU_CORE);
|
dtm->CPUCore = Config::Get(Config::MAIN_CPU_CORE);
|
||||||
dtm->bSyncGPU = config_layer->Get(Config::MAIN_SYNC_GPU);
|
dtm->bSyncGPU = Config::Get(Config::MAIN_SYNC_GPU);
|
||||||
const std::string video_backend = config_layer->Get(Config::MAIN_GFX_BACKEND);
|
const std::string video_backend = Config::Get(Config::MAIN_GFX_BACKEND);
|
||||||
|
|
||||||
dtm->bProgressive = config_layer->Get(Config::SYSCONF_PROGRESSIVE_SCAN);
|
dtm->bProgressive = Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN);
|
||||||
dtm->bPAL60 = config_layer->Get(Config::SYSCONF_PAL60);
|
dtm->bPAL60 = Config::Get(Config::SYSCONF_PAL60);
|
||||||
if (dtm->bWii)
|
if (dtm->bWii)
|
||||||
dtm->language = config_layer->Get(Config::SYSCONF_LANGUAGE);
|
dtm->language = Config::Get(Config::SYSCONF_LANGUAGE);
|
||||||
else
|
else
|
||||||
dtm->language = config_layer->Get(Config::MAIN_GC_LANGUAGE);
|
dtm->language = Config::Get(Config::MAIN_GC_LANGUAGE);
|
||||||
|
|
||||||
dtm->bUseXFB = config_layer->Get(Config::GFX_USE_XFB);
|
dtm->bUseXFB = Config::Get(Config::GFX_USE_XFB);
|
||||||
dtm->bUseRealXFB = config_layer->Get(Config::GFX_USE_REAL_XFB);
|
dtm->bUseRealXFB = Config::Get(Config::GFX_USE_REAL_XFB);
|
||||||
dtm->bEFBAccessEnable = config_layer->Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
|
dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
|
||||||
dtm->bSkipEFBCopyToRam = config_layer->Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
|
dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
|
||||||
dtm->bEFBEmulateFormatChanges = config_layer->Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
|
dtm->bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
|
||||||
|
|
||||||
// This never used the regular config
|
// This never used the regular config
|
||||||
dtm->bSkipIdle = true;
|
dtm->bSkipIdle = true;
|
||||||
|
|
|
@ -30,6 +30,6 @@ private:
|
||||||
Movie::DTMHeader* m_header;
|
Movie::DTMHeader* m_header;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SaveToDTM(Config::Layer* layer, Movie::DTMHeader* header);
|
void SaveToDTM(Movie::DTMHeader* header);
|
||||||
std::unique_ptr<Config::ConfigLayerLoader> GenerateMovieConfigLoader(Movie::DTMHeader* header);
|
std::unique_ptr<Config::ConfigLayerLoader> GenerateMovieConfigLoader(Movie::DTMHeader* header);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Common/Config/Config.h"
|
#include "Common/Config/Config.h"
|
||||||
|
#include "Core/Config/MainSettings.h"
|
||||||
#include "Core/Config/SYSCONFSettings.h"
|
#include "Core/Config/SYSCONFSettings.h"
|
||||||
#include "Core/NetPlayProto.h"
|
#include "Core/NetPlayProto.h"
|
||||||
|
|
||||||
|
@ -20,29 +21,26 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Load(Config::Layer* config_layer) override
|
void Load(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
Config::Section* core = config_layer->GetOrCreateSection(Config::System::Main, "Core");
|
layer->Set(Config::MAIN_CPU_THREAD, m_settings.m_CPUthread);
|
||||||
Config::Section* dsp = config_layer->GetOrCreateSection(Config::System::Main, "DSP");
|
layer->Set(Config::MAIN_CPU_CORE, m_settings.m_CPUcore);
|
||||||
|
layer->Set(Config::MAIN_GC_LANGUAGE, m_settings.m_SelectedLanguage);
|
||||||
|
layer->Set(Config::MAIN_OVERRIDE_GC_LANGUAGE, m_settings.m_OverrideGCLanguage);
|
||||||
|
layer->Set(Config::MAIN_DSP_HLE, m_settings.m_DSPHLE);
|
||||||
|
layer->Set(Config::MAIN_OVERCLOCK_ENABLE, m_settings.m_OCEnable);
|
||||||
|
layer->Set(Config::MAIN_OVERCLOCK, m_settings.m_OCFactor);
|
||||||
|
layer->Set(Config::MAIN_SLOT_A, static_cast<int>(m_settings.m_EXIDevice[0]));
|
||||||
|
layer->Set(Config::MAIN_SLOT_B, static_cast<int>(m_settings.m_EXIDevice[1]));
|
||||||
|
layer->Set(Config::MAIN_WII_SD_CARD_WRITABLE, m_settings.m_WriteToMemcard);
|
||||||
|
|
||||||
core->Set("CPUThread", m_settings.m_CPUthread);
|
layer->Set(Config::MAIN_DSP_JIT, m_settings.m_DSPEnableJIT);
|
||||||
core->Set("CPUCore", m_settings.m_CPUcore);
|
|
||||||
core->Set("SelectedLanguage", m_settings.m_SelectedLanguage);
|
|
||||||
core->Set("OverrideGCLang", m_settings.m_OverrideGCLanguage);
|
|
||||||
core->Set("DSPHLE", m_settings.m_DSPHLE);
|
|
||||||
core->Set("OverclockEnable", m_settings.m_OCEnable);
|
|
||||||
core->Set("Overclock", m_settings.m_OCFactor);
|
|
||||||
core->Set("SlotA", m_settings.m_EXIDevice[0]);
|
|
||||||
core->Set("SlotB", m_settings.m_EXIDevice[1]);
|
|
||||||
core->Set("EnableSaving", m_settings.m_WriteToMemcard);
|
|
||||||
|
|
||||||
dsp->Set("EnableJIT", m_settings.m_DSPEnableJIT);
|
layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan);
|
||||||
|
layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60);
|
||||||
config_layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan);
|
|
||||||
config_layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Save(Config::Layer* config_layer) override
|
void Save(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -1306,7 +1306,7 @@ void SaveRecording(const std::string& filename)
|
||||||
header.recordingStartTime = s_recordingStartTime;
|
header.recordingStartTime = s_recordingStartTime;
|
||||||
|
|
||||||
header.bSaveConfig = true;
|
header.bSaveConfig = true;
|
||||||
ConfigLoaders::SaveToDTM(Config::GetLayer(Config::LayerType::Meta), &header);
|
ConfigLoaders::SaveToDTM(&header);
|
||||||
header.memcards = s_memcards;
|
header.memcards = s_memcards;
|
||||||
header.bClearSave = s_bClearSave;
|
header.bClearSave = s_bClearSave;
|
||||||
header.bNetPlay = s_bNetPlay;
|
header.bNetPlay = s_bNetPlay;
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
#include <OptionParser.h>
|
#include <OptionParser.h>
|
||||||
|
|
||||||
#include "Common/Config/Config.h"
|
#include "Common/Config/Config.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/Version.h"
|
#include "Common/Version.h"
|
||||||
|
#include "Core/Config/MainSettings.h"
|
||||||
#include "UICommon/CommandLineParse.h"
|
#include "UICommon/CommandLineParse.h"
|
||||||
|
|
||||||
namespace CommandLineParse
|
namespace CommandLineParse
|
||||||
|
@ -23,42 +25,41 @@ public:
|
||||||
: ConfigLayerLoader(Config::LayerType::CommandLine)
|
: ConfigLayerLoader(Config::LayerType::CommandLine)
|
||||||
{
|
{
|
||||||
if (video_backend.size())
|
if (video_backend.size())
|
||||||
m_values.emplace_back(std::make_tuple("Dolphin", "Core", "GFXBackend", video_backend));
|
m_values.emplace_back(std::make_tuple(Config::MAIN_GFX_BACKEND.location, video_backend));
|
||||||
|
|
||||||
if (audio_backend.size())
|
if (audio_backend.size())
|
||||||
m_values.emplace_back(
|
m_values.emplace_back(
|
||||||
std::make_tuple("Dolphin", "Core", "DSPHLE", audio_backend == "HLE" ? "True" : "False"));
|
std::make_tuple(Config::MAIN_DSP_HLE.location, StringFromBool(audio_backend == "HLE")));
|
||||||
|
|
||||||
// Arguments are in the format of <System>.<Section>.<Key>=Value
|
// Arguments are in the format of <System>.<Section>.<Key>=Value
|
||||||
for (const auto& arg : args)
|
for (const auto& arg : args)
|
||||||
{
|
{
|
||||||
std::istringstream buffer(arg);
|
std::istringstream buffer(arg);
|
||||||
std::string system, section, key, value;
|
std::string system_str, section, key, value;
|
||||||
std::getline(buffer, system, '.');
|
std::getline(buffer, system_str, '.');
|
||||||
std::getline(buffer, section, '.');
|
std::getline(buffer, section, '.');
|
||||||
std::getline(buffer, key, '=');
|
std::getline(buffer, key, '=');
|
||||||
std::getline(buffer, value, '=');
|
std::getline(buffer, value, '=');
|
||||||
m_values.emplace_back(std::make_tuple(system, section, key, value));
|
Config::System system = Config::GetSystemFromName(system_str);
|
||||||
|
m_values.emplace_back(std::make_tuple(Config::ConfigLocation{system, section, key}, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Load(Config::Layer* config_layer) override
|
void Load(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
for (auto& value : m_values)
|
for (auto& value : m_values)
|
||||||
{
|
{
|
||||||
Config::Section* section = config_layer->GetOrCreateSection(
|
layer->Set(std::get<0>(value), std::get<1>(value));
|
||||||
Config::GetSystemFromName(std::get<0>(value)), std::get<1>(value));
|
|
||||||
section->Set(std::get<2>(value), std::get<3>(value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Save(Config::Layer* config_layer) override
|
void Save(Config::Layer* layer) override
|
||||||
{
|
{
|
||||||
// Save Nothing
|
// Save Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<std::tuple<std::string, std::string, std::string, std::string>> m_values;
|
std::list<std::tuple<Config::ConfigLocation, std::string>> m_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<optparse::OptionParser> CreateParser(ParserOptions options)
|
std::unique_ptr<optparse::OptionParser> CreateParser(ParserOptions options)
|
||||||
|
|
Loading…
Reference in New Issue