Change how defaults work in the inifile reader (more flexible this way)

This commit is contained in:
Henrik Rydgård 2025-10-31 16:20:29 +01:00
parent c98b7591d3
commit 14ddad5ce3
14 changed files with 269 additions and 184 deletions

View File

@ -262,16 +262,12 @@ void Section::Set(std::string_view key, std::string_view newValue, std::string_
Delete(key);
}
bool Section::Get(std::string_view key, std::string* value, const char* defaultValue) const {
bool Section::Get(std::string_view key, std::string *value) const {
const ParsedIniLine *line = GetLine(key);
if (!line) {
if (defaultValue) {
*value = defaultValue;
}
return false;
} else {
*value = line->Value();
}
*value = line->Value();
return true;
}
@ -314,69 +310,62 @@ void Section::Set(std::string_view key, const std::vector<std::string> &newValue
bool Section::Get(std::string_view key, std::vector<std::string> *values, const std::vector<std::string_view> *defaultValues) const {
std::string temp;
bool retval = Get(key, &temp, 0);
if (!retval || temp.empty()) {
bool retval = Get(key, &temp);
if (!retval) {
if (defaultValues) {
CopyStrings(values, *defaultValues);
}
return false;
}
SplitString(temp, ',', *values, true);
return true;
}
bool Section::Get(std::string_view key, int* value, int defaultValue) const {
bool Section::Get(std::string_view key, int *value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
bool Section::Get(std::string_view key, uint32_t* value, uint32_t defaultValue) const {
bool Section::Get(std::string_view key, uint32_t *value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
bool Section::Get(std::string_view key, uint64_t* value, uint64_t defaultValue) const {
bool Section::Get(std::string_view key, uint64_t *value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
bool Section::Get(std::string_view key, bool* value, bool defaultValue) const {
bool Section::Get(std::string_view key, bool *value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
bool Section::Get(std::string_view key, float* value, float defaultValue) const {
bool Section::Get(std::string_view key, float *value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
bool Section::Get(std::string_view key, double* value, double defaultValue) const {
bool Section::Get(std::string_view key, double* value) const {
std::string temp;
bool retval = Get(key, &temp, 0);
bool retval = Get(key, &temp);
if (retval && TryParse(temp, value))
return true;
*value = defaultValue;
return false;
}
@ -415,7 +404,7 @@ bool Section::Delete(std::string_view key) {
// IniFile
const Section* IniFile::GetSection(std::string_view sectionName) const {
const Section *IniFile::GetSection(std::string_view sectionName) const {
for (const auto &iter : sections)
if (equalsNoCase(iter->name(), sectionName))
return iter.get();
@ -581,60 +570,54 @@ bool IniFile::Save(const Path &filename)
return true;
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, std::string* value, const char *defaultValue) {
Section* section = GetSection(sectionName);
bool IniFile::Get(std::string_view sectionName, std::string_view key, std::string *value) const {
const Section *section = GetSection(sectionName);
if (!section) {
if (defaultValue) {
*value = defaultValue;
}
return false;
}
return section->Get(key, value, defaultValue);
return section->Get(key, value);
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, std::vector<std::string> *values, const std::vector<std::string_view> *defaultValues) {
Section *section = GetSection(sectionName);
if (!section)
return false;
return section->Get(key, values, defaultValues);
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, int *value, int defaultValue) {
Section *section = GetSection(sectionName);
bool IniFile::Get(std::string_view sectionName, std::string_view key, std::vector<std::string> *values) const {
const Section *section = GetSection(sectionName);
if (!section) {
return false;
}
return section->Get(key, values);
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, int *value) const {
const Section *section = GetSection(sectionName);
if (!section) {
*value = defaultValue;
return false;
} else {
return section->Get(key, value, defaultValue);
return section->Get(key, value);
}
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, uint32_t *value, uint32_t defaultValue) {
Section *section = GetSection(sectionName);
bool IniFile::Get(std::string_view sectionName, std::string_view key, uint32_t *value) const {
const Section *section = GetSection(sectionName);
if (!section) {
*value = defaultValue;
return false;
} else {
return section->Get(key, value, defaultValue);
return section->Get(key, value);
}
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, uint64_t *value, uint64_t defaultValue) {
Section *section = GetSection(sectionName);
bool IniFile::Get(std::string_view sectionName, std::string_view key, uint64_t *value) const {
const Section *section = GetSection(sectionName);
if (!section) {
*value = defaultValue;
return false;
} else {
return section->Get(key, value, defaultValue);
return section->Get(key, value);
}
}
bool IniFile::Get(std::string_view sectionName, std::string_view key, bool *value, bool defaultValue) {
Section *section = GetSection(sectionName);
bool IniFile::Get(std::string_view sectionName, std::string_view key, bool *value) const {
const Section *section = GetSection(sectionName);
if (!section) {
*value = defaultValue;
return false;
} else {
return section->Get(key, value, defaultValue);
return section->Get(key, value);
}
}

View File

@ -68,8 +68,6 @@ public:
void Set(std::string_view key, std::string_view newValue);
void Set(std::string_view key, std::string_view newValue, std::string_view defaultValue);
bool Get(std::string_view key, std::string *value, const char* defaultValue) const;
void Set(std::string_view key, uint32_t newValue);
void Set(std::string_view key, uint64_t newValue);
void Set(std::string_view key, float newValue);
@ -88,12 +86,13 @@ public:
void AddComment(std::string_view comment);
bool Get(std::string_view key, int* value, int defaultValue = 0) const;
bool Get(std::string_view key, uint32_t* value, uint32_t defaultValue = 0) const;
bool Get(std::string_view key, uint64_t* value, uint64_t defaultValue = 0) const;
bool Get(std::string_view key, bool* value, bool defaultValue = false) const;
bool Get(std::string_view key, float* value, float defaultValue = false) const;
bool Get(std::string_view key, double* value, double defaultValue = false) const;
bool Get(std::string_view key, std::string *value) const;
bool Get(std::string_view key, int* value) const;
bool Get(std::string_view key, uint32_t* value) const;
bool Get(std::string_view key, uint64_t* value) const;
bool Get(std::string_view key, bool* value) const;
bool Get(std::string_view key, float* value) const;
bool Get(std::string_view key, double* value) const;
bool Get(std::string_view key, std::vector<std::string> *values, const std::vector<std::string_view> *defaultValue = nullptr) const;
// Return a list of all keys in this section
@ -130,12 +129,12 @@ public:
bool Exists(std::string_view sectionName, std::string_view key) const;
// These will not create the section if it doesn't exist.
bool Get(std::string_view sectionName, std::string_view key, std::string* value, const char* defaultValue = "");
bool Get(std::string_view sectionName, std::string_view key, int* value, int defaultValue = 0);
bool Get(std::string_view sectionName, std::string_view key, uint32_t* value, uint32_t defaultValue = 0);
bool Get(std::string_view sectionName, std::string_view key, uint64_t* value, uint64_t defaultValue = 0);
bool Get(std::string_view sectionName, std::string_view key, bool* value, bool defaultValue = false);
bool Get(std::string_view sectionName, std::string_view key, std::vector<std::string> *values, const std::vector<std::string_view> *defaultValues = nullptr);
bool Get(std::string_view sectionName, std::string_view key, std::string *value) const;
bool Get(std::string_view sectionName, std::string_view key, int* value) const;
bool Get(std::string_view sectionName, std::string_view key, uint32_t* value) const;
bool Get(std::string_view sectionName, std::string_view key, uint64_t* value) const;
bool Get(std::string_view sectionName, std::string_view key, bool* value) const;
bool Get(std::string_view sectionName, std::string_view key, std::vector<std::string> *values) const;
bool GetKeys(std::string_view sectionName, std::vector<std::string>& keys) const;

View File

@ -219,10 +219,11 @@ void LogManager::SaveConfig(Section *section) {
void LogManager::LoadConfig(const Section *section) {
for (int i = 0; i < (int)Log::NUMBER_OF_LOGS; i++) {
bool enabled = false;
int level = 0;
section->Get((std::string(g_logTypeNames[i]) + "Enabled"), &enabled, true);
section->Get((std::string(g_logTypeNames[i]) + "Level"), &level, (int)LogLevel::LERROR);
// Defaults. Get now doesn't write the output if it fails.
bool enabled = true;
int level = (int)LogLevel::LERROR;
section->Get((std::string(g_logTypeNames[i]) + "Enabled"), &enabled);
section->Get((std::string(g_logTypeNames[i]) + "Level"), &level);
g_log[i].enabled = enabled;
g_log[i].level = (LogLevel)level;
}

View File

@ -170,11 +170,11 @@ void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID)
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) {
if (ignored_.find(option) == ignored_.end()) {
iniFile.Get(option, gameID.c_str(), flag, *flag);
iniFile.Get(option, gameID.c_str(), flag);
// Shortcut for debugging, sometimes useful to globally enable compat flags.
bool all = false;
iniFile.Get(option, "ALL", &all, false);
iniFile.Get(option, "ALL", &all);
if (all) {
*flag |= all;
if (!activeList_.empty()) {
@ -187,14 +187,14 @@ void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, co
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, float *flag) {
std::string value;
if (iniFile.Get(option, gameID.c_str(), &value, "0")) {
if (iniFile.Get(option, gameID.c_str(), &value)) {
*flag = stof(value);
}
}
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, int *flag) {
std::string value;
if (iniFile.Get(option, gameID.c_str(), &value, "0")) {
if (iniFile.Get(option, gameID.c_str(), &value)) {
*flag = stof(value);
}
}

View File

@ -1100,7 +1100,7 @@ std::map<const void *, const ConfigSetting *> &Config::getPtrLUT() {
Config::Config() {
// Initialize the pointer->setting lookup map.
auto ref = getPtrLUT();
IterateSettings([this, &ref](const char *owner, const ConfigSetting &setting) {
IterateSettings([&ref](const char *owner, const ConfigSetting &setting) {
const void *ptr = setting.GetVoidPtr(owner);
ref[ptr] = &setting;
});
@ -1137,9 +1137,11 @@ void Config::LoadLangValuesMapping() {
for (size_t i = 0; i < keys.size(); i++) {
std::string langName;
langRegionNames->Get(keys[i], &langName, "ERROR");
std::string langCode;
systemLanguage->Get(keys[i], &langCode, "ENGLISH");
if (!langRegionNames->Get(keys[i], &langName)) {
continue;
}
std::string langCode = "ENGLISH";;
systemLanguage->Get(keys[i], &langCode);
int iLangCode = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
if (langCodeMapping.find(langCode) != langCodeMapping.end())
iLangCode = langCodeMapping[langCode];
@ -1240,7 +1242,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
g_logManager.LoadConfig(log);
Section *recent = iniFile.GetOrCreateSection("Recent");
recent->Get("MaxRecent", &iMaxRecent, 60);
iMaxRecent = 60;
recent->Get("MaxRecent", &iMaxRecent);
// Fix issue from switching from uint (hex in .ini) to int (dec)
// -1 is okay, though. We'll just ignore recent stuff if it is.
@ -1309,8 +1312,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
// Check for an old dpad setting (very obsolete)
Section *control = iniFile.GetSection("Control");
if (control) {
float f;
control->Get("DPadRadius", &f, 0.0f);
float f = 0.0f;
control->Get("DPadRadius", &f);
if (f > 0.0f) {
ResetControlLayout();
}

View File

@ -15,25 +15,66 @@ bool ConfigSetting::perGame(void *ptr) {
bool ConfigSetting::ReadFromIniSection(char *owner, const Section *section) const {
switch (type_) {
case Type::TYPE_BOOL:
return section->Get(iniKey_, (bool *)(owner + offset_), cb_.b ? cb_.b() : default_.b);
{
bool *target = (bool *)(owner + offset_);
if (!section->Get(iniKey_, target)) {
*target = cb_.b ? cb_.b() : default_.b;
return false;
}
return true;
}
case Type::TYPE_INT:
{
int *target = (int *)(owner + offset_);
if (translateFrom_) {
std::string value;
if (section->Get(iniKey_, &value, nullptr)) {
if (section->Get(iniKey_, &value)) {
*((int *)(owner + offset_)) = translateFrom_(value);
return true;
}
}
return section->Get(iniKey_, (int *)(owner + offset_), cb_.i ? cb_.i() : default_.i);
if (!section->Get(iniKey_, target)) {
*target = cb_.i ? cb_.i() : default_.i;
return false;
}
return true;
}
case Type::TYPE_UINT32:
return section->Get(iniKey_, (uint32_t *)(owner + offset_), cb_.u ? cb_.u() : default_.u);
{
uint32_t *target = (uint32_t *)(owner + offset_);
if (!section->Get(iniKey_, target)) {
*target = cb_.u ? cb_.u() : default_.u;
return false;
}
return true;
}
case Type::TYPE_UINT64:
return section->Get(iniKey_, (uint64_t *)(owner + offset_), cb_.lu ? cb_.lu() : default_.lu);
{
uint64_t *target = (uint64_t *)(owner + offset_);
if (!section->Get(iniKey_, target)) {
*target = cb_.lu ? cb_.lu() : default_.lu;
return false;
}
return true;
}
case Type::TYPE_FLOAT:
return section->Get(iniKey_, (float *)(owner + offset_), cb_.f ? cb_.f() : default_.f);
{
float *target = (float *)(owner + offset_);
if (!section->Get(iniKey_, target)) {
*target = cb_.f ? cb_.f() : default_.f;
return false;
}
return true;
}
case Type::TYPE_STRING:
return section->Get(iniKey_, (std::string *)(owner + offset_), cb_.s ? cb_.s().c_str() : default_.s);
{
std::string *target = (std::string *)(owner + offset_);
if (!section->Get(iniKey_, target)) {
*target = cb_.s ? cb_.s().c_str() : default_.s;
return false;
}
return true;
}
case Type::TYPE_STRING_VECTOR:
{
// No support for callbacks for these yet. that's not an issue.
@ -49,11 +90,17 @@ bool ConfigSetting::ReadFromIniSection(char *owner, const Section *section) cons
ConfigTouchPos defaultTouchPos = cb_.touchPos ? cb_.touchPos() : default_.touchPos;
ConfigTouchPos *touchPos = ((ConfigTouchPos *)(owner + offset_));
section->Get(iniKey_, &touchPos->x, defaultTouchPos.x);
section->Get(ini2_, &touchPos->y, defaultTouchPos.y);
section->Get(ini3_, &touchPos->scale, defaultTouchPos.scale);
if (ini4_) {
section->Get(ini4_, &touchPos->show, defaultTouchPos.show);
if (!section->Get(iniKey_, &touchPos->x)) {
touchPos->x = defaultTouchPos.x;
}
if (!section->Get(ini2_, &touchPos->y)) {
touchPos->y = defaultTouchPos.y;
}
if (!section->Get(ini3_, &touchPos->scale)) {
touchPos->scale = defaultTouchPos.scale;
}
if (ini4_ && section->Get(ini4_, &touchPos->show)) {
// do nothing, succeeded.
} else {
touchPos->show = defaultTouchPos.show;
}
@ -61,24 +108,39 @@ bool ConfigSetting::ReadFromIniSection(char *owner, const Section *section) cons
}
case Type::TYPE_PATH:
{
Path *target = (Path *)(owner + offset_);
std::string tmp;
bool result = section->Get(iniKey_, &tmp, cb_.p ? cb_.p() : default_.p);
if (result) {
Path *path = (Path *)(owner + offset_);
*path = Path(tmp);
if (!section->Get(iniKey_, &tmp)) {
if (cb_.p) {
*target = cb_.p();
} else {
*target = Path(default_.p);
}
return false;
}
return result;
*target = Path(tmp);
return true;
}
case Type::TYPE_CUSTOM_BUTTON:
{
ConfigCustomButton defaultCustomButton = cb_.customButton ? cb_.customButton() : default_.customButton;
ConfigCustomButton *customButton = ((ConfigCustomButton *)(owner + offset_));
section->Get(iniKey_, &customButton->key, defaultCustomButton.key);
section->Get(ini2_, &customButton->image, defaultCustomButton.image);
section->Get(ini3_, &customButton->shape, defaultCustomButton.shape);
section->Get(ini4_, &customButton->toggle, defaultCustomButton.toggle);
section->Get(ini5_, &customButton->repeat, defaultCustomButton.repeat);
if (!section->Get(iniKey_, &customButton->key)) {
customButton->key = defaultCustomButton.key;
}
if (!section->Get(ini2_, &customButton->image)) {
customButton->image = defaultCustomButton.image;
}
if (!section->Get(ini3_, &customButton->shape)) {
customButton->shape = defaultCustomButton.shape;
}
if (!section->Get(ini4_, &customButton->toggle)) {
customButton->toggle = defaultCustomButton.toggle;
}
if (!section->Get(ini5_, &customButton->repeat)) {
customButton->repeat = defaultCustomButton.repeat;
}
return true;
}
default:
@ -221,7 +283,13 @@ bool ConfigSetting::RestoreToDefault(const char *owner, bool log) const {
{
std::string *ptr_s = (std::string *)(owner + offset_);
const std::string origValue = *ptr_s;
*ptr_s = cb_.s ? cb_.s() : default_.s;
if (cb_.s) {
*ptr_s = cb_.s();
} else if (default_.s != nullptr) {
*ptr_s = default_.s;
} else {
*ptr_s = "";
}
if (*ptr_s != origValue) {
if (log) {
INFO_LOG(Log::System, "Restored %.*s from \"%s\" to default \"%s\"", STR_VIEW(iniKey_),
@ -246,7 +314,14 @@ bool ConfigSetting::RestoreToDefault(const char *owner, bool log) const {
case Type::TYPE_PATH:
{
Path *ptr_path = (Path *)(owner + offset_);
*ptr_path = Path(cb_.p ? cb_.p() : default_.p);
if (cb_.p) {
*ptr_path = cb_.p();
break;
} else if (default_.p) {
*ptr_path = Path(default_.p);
} else {
ptr_path->clear();
}
break;
}
case Type::TYPE_CUSTOM_BUTTON:

View File

@ -62,7 +62,7 @@ struct ConfigSetting {
typedef float (*FloatDefaultCallback)();
typedef std::string (*StringDefaultCallback)();
typedef ConfigTouchPos (*TouchPosDefaultCallback)();
typedef const char *(*PathDefaultCallback)();
typedef Path (*PathDefaultCallback)();
typedef ConfigCustomButton (*CustomButtonDefaultCallback)();
union DefaultCallback {

View File

@ -47,25 +47,29 @@ static PluginInfo ReadPluginIni(const std::string &subdir, IniFile &ini) {
auto options = ini.GetOrCreateSection("options");
std::string value;
if (options->Get("type", &value, "")) {
if (options->Get("type", &value)) {
if (value == "prx") {
info.type = PluginType::PRX;
}
}
if (options->Get("filename", &value, "")) {
value.clear();
if (options->Get("filename", &value)) {
info.name = value;
info.filename = "ms0:/PSP/PLUGINS/" + subdir + "/" + value;
} else {
info.type = PluginType::INVALID;
}
if (options->Get("name", &value, "")) {
value.clear();
if (options->Get("name", &value)) {
info.name = value;
}
options->Get("version", &info.version, 0);
options->Get("memory", &info.memory, 0);
info.version = 0;
info.memory = 0;
options->Get("version", &info.version);
options->Get("memory", &info.memory);
if (info.memory > 93) {
ERROR_LOG(Log::System, "Plugin memory too high, using 93 MB");
info.memory = 93;
@ -105,7 +109,8 @@ std::vector<PluginInfo> FindPlugins(const std::string &gameID, const std::string
// TODO: Should just use getsection and fail the ini if not found, I guess.
const Section *games = ini.GetSection("games");
if (games) {
if (games->Get(gameID.c_str(), &gameIni, "")) {
gameIni.clear();
if (games->Get(gameID.c_str(), &gameIni)) {
if (!strcasecmp(gameIni.c_str(), "true")) {
matches.insert("plugin.ini");
} else if (!strcasecmp(gameIni.c_str(), "false")) {
@ -114,8 +119,8 @@ std::vector<PluginInfo> FindPlugins(const std::string &gameID, const std::string
matches.insert(gameIni);
}
}
if (games->Get("ALL", &gameIni, "")) {
gameIni.clear();
if (games->Get("ALL", &gameIni)) {
if (!strcasecmp(gameIni.c_str(), "true")) {
matches.insert("plugin.ini");
} else if (!gameIni.empty()) {
@ -132,8 +137,8 @@ std::vector<PluginInfo> FindPlugins(const std::string &gameID, const std::string
}
found.push_back(ReadPluginIni(subdir.name, ini));
if (ini.GetOrCreateSection("lang")->Get(lang.c_str(), &gameIni, "")) {
gameIni.clear();
if (ini.GetOrCreateSection("lang")->Get(lang.c_str(), &gameIni)) {
if (!gameIni.empty() && matches.find(gameIni) == matches.end()) {
langMatches.insert(gameIni);
}

View File

@ -761,7 +761,7 @@ void LoadFromIni(IniFile &file) {
Section *controls = file.GetOrCreateSection("ControlMapping");
for (size_t i = 0; i < ARRAY_SIZE(psp_button_names); i++) {
std::string value;
controls->Get(psp_button_names[i].name, &value, "");
controls->Get(psp_button_names[i].name, &value);
// Erase default mapping
g_controllerMap.erase(psp_button_names[i].key);

View File

@ -89,7 +89,7 @@ void RecentFilesManager::Load(const Section *recent, int maxRecent) {
std::string fileName;
snprintf(keyName, sizeof(keyName), "FileName%d", i);
if (recent->Get(keyName, &fileName, "") && !fileName.empty()) {
if (recent->Get(keyName, &fileName) && !fileName.empty()) {
newRecent.push_back(fileName);
}
}

View File

@ -99,8 +99,8 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
// Alright, let's loop through the sections and see if any is a shader.
for (size_t i = 0; i < ini.Sections().size(); i++) {
Section &section = *(ini.Sections()[i].get());
std::string shaderType;
section.Get("Type", &shaderType, "render");
std::string shaderType = "render";
section.Get("Type", &shaderType);
std::vector<std::string> vendorBlacklist;
section.Get("VendorBlacklist", &vendorBlacklist, nullptr);
@ -144,19 +144,22 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
ShaderInfo info{};
std::string temp;
info.section = section.name();
section.Get("Name", &info.name, section.name().c_str());
section.Get("Parent", &info.parent, "");
section.Get("Visible", &info.visible, true);
section.Get("Fragment", &temp, "");
info.name = section.name();
info.visible = true;
section.Get("Name", &info.name);
section.Get("Parent", &info.parent);
section.Get("Visible", &info.visible);
temp.clear();
section.Get("Fragment", &temp);
info.fragmentShaderFile = path / temp;
section.Get("Vertex", &temp, "");
temp.clear();
section.Get("Vertex", &temp);
info.vertexShaderFile = path / temp;
section.Get("OutputResolution", &info.outputResolution, false);
section.Get("Upscaling", &info.isUpscalingFilter, false);
section.Get("SSAA", &info.SSAAFilterLevel, 0);
section.Get("60fps", &info.requires60fps, false);
section.Get("UsePreviousFrame", &info.usePreviousFrame, false);
section.Get("OutputResolution", &info.outputResolution);
section.Get("Upscaling", &info.isUpscalingFilter);
section.Get("SSAA", &info.SSAAFilterLevel);
section.Get("60fps", &info.requires60fps);
section.Get("UsePreviousFrame", &info.usePreviousFrame);
if (info.parent == "Off")
info.parent.clear();
@ -169,17 +172,22 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
for (size_t i = 0; i < ARRAY_SIZE(info.settings); ++i) {
auto &setting = info.settings[i];
section.Get(StringFromFormat("SettingName%d", i + 1).c_str(), &setting.name, "");
section.Get(StringFromFormat("SettingDefaultValue%d", i + 1).c_str(), &setting.value, 0.0f);
section.Get(StringFromFormat("SettingMinValue%d", i + 1).c_str(), &setting.minValue, -1.0f);
section.Get(StringFromFormat("SettingMaxValue%d", i + 1).c_str(), &setting.maxValue, 1.0f);
section.Get(StringFromFormat("SettingStep%d", i + 1).c_str(), &setting.step, 0.01f);
setting.name.clear();
setting.value = 0.0;
setting.minValue = -1.0f;
setting.maxValue = 1.0f;
setting.step = 0.01f;
section.Get(StringFromFormat("SettingName%d", i + 1).c_str(), &setting.name);
section.Get(StringFromFormat("SettingDefaultValue%d", i + 1).c_str(), &setting.value);
section.Get(StringFromFormat("SettingMinValue%d", i + 1).c_str(), &setting.minValue);
section.Get(StringFromFormat("SettingMaxValue%d", i + 1).c_str(), &setting.maxValue);
section.Get(StringFromFormat("SettingStep%d", i + 1).c_str(), &setting.step);
}
// Let's ignore shaders we can't support. TODO: Not a very good check
if (gl_extensions.IsGLES && !gl_extensions.GLES3) {
bool requiresIntegerSupport;
section.Get("RequiresIntSupport", &requiresIntegerSupport, false);
bool requiresIntegerSupport = false;
section.Get("RequiresIntSupport", &requiresIntegerSupport);
if (requiresIntegerSupport)
continue;
}
@ -194,12 +202,17 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
TextureShaderInfo info{};
std::string temp;
info.section = section.name();
section.Get("Name", &info.name, section.name().c_str());
section.Get("Compute", &temp, "");
section.Get("Scale", &info.scaleFactor, 0);
info.computeShaderFile = path / temp;
if (info.scaleFactor >= 2 && info.scaleFactor < 8) {
appendTextureShader(info);
info.name = section.name();
info.scaleFactor = 0;
section.Get("Name", &info.name);
section.Get("Scale", &info.scaleFactor);
if (section.Get("Compute", &temp)) {
info.computeShaderFile = path / temp;
if (info.scaleFactor >= 2 && info.scaleFactor < 8) {
appendTextureShader(info);
}
} else {
ERROR_LOG(Log::G3D, "Compute field missing for compute shader");
}
} else if (!section.name().empty()) {
WARN_LOG(Log::G3D, "Unrecognized shader type '%s' or invalid shader in section '%s'", shaderType.c_str(), section.name().c_str());

View File

@ -155,7 +155,7 @@ bool TextureReplacer::LoadIni(std::string *error, bool notify) {
// Allow overriding settings per game id.
std::string overrideFilename;
if (ini.GetOrCreateSection("games")->Get(gameID_.c_str(), &overrideFilename, "")) {
if (ini.GetOrCreateSection("games")->Get(gameID_.c_str(), &overrideFilename)) {
if (overrideFilename == "true") {
// Ignore it
} else if (!overrideFilename.empty() && overrideFilename != INI_FILENAME) {
@ -287,7 +287,7 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri
auto options = ini.GetOrCreateSection("options");
std::string hash;
if (!options->Get("hash", &hash, "")) {
if (!options->Get("hash", &hash)) {
*error = "textures.ini: Hash type not specified";
return false;
}
@ -302,12 +302,12 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri
return false;
}
options->Get("video", &allowVideo_, allowVideo_);
options->Get("ignoreAddress", &ignoreAddress_, ignoreAddress_);
options->Get("video", &allowVideo_);
options->Get("ignoreAddress", &ignoreAddress_);
// Multiplies sizeInRAM/bytesPerLine in XXHASH by 0.5.
options->Get("reduceHash", &reduceHash_, reduceHash_);
options->Get("ignoreMipmap", &ignoreMipmap_, ignoreMipmap_);
options->Get("skipLastDXT1Blocks128x64", &skipLastDXT1Blocks128x64_, skipLastDXT1Blocks128x64_);
options->Get("reduceHash", &reduceHash_);
options->Get("ignoreMipmap", &ignoreMipmap_);
options->Get("skipLastDXT1Blocks128x64", &skipLastDXT1Blocks128x64_);
if (reduceHash_ && hash_ == ReplacedTextureHash::QUICK) {
reduceHash_ = false;
ERROR_LOG(Log::TexReplacement, "Texture Replacement: reduceHash option requires safer hash, use xxh32 or xxh64 instead.");
@ -319,7 +319,7 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri
}
int version = 0;
if (options->Get("version", &version, 0) && version > VERSION) {
if (options->Get("version", &version) && version > VERSION) {
ERROR_LOG(Log::TexReplacement, "Unsupported texture replacement version %d, trying anyway", version);
}

View File

@ -2797,7 +2797,9 @@ public:
if (save_) {
section_->Set(key, *value);
} else {
section_->Get(key, value, defaultValue);
if (!section_->Get(key, value)) {
*value = defaultValue;
}
}
}
private:

View File

@ -125,33 +125,37 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
}
ThemeInfo info;
section.Get("Name", &info.name, section.name().c_str());
info.name = section.name();
section.Get("Name", &info.name);
section.Get("ItemStyleFg", &info.uItemStyleFg, info.uItemStyleFg);
section.Get("ItemStyleBg", &info.uItemStyleBg, info.uItemStyleBg);
section.Get("ItemFocusedStyleFg", &info.uItemFocusedStyleFg, info.uItemFocusedStyleFg);
section.Get("ItemFocusedStyleBg", &info.uItemFocusedStyleBg, info.uItemFocusedStyleBg);
section.Get("ItemDownStyleFg", &info.uItemDownStyleFg, info.uItemDownStyleFg);
section.Get("ItemDownStyleBg", &info.uItemDownStyleBg, info.uItemDownStyleBg);
section.Get("ItemDisabledStyleFg", &info.uItemDisabledStyleFg, info.uItemDisabledStyleFg);
section.Get("ItemDisabledStyleBg", &info.uItemDisabledStyleBg, info.uItemDisabledStyleBg);
section.Get("ItemStyleFg", &info.uItemStyleFg);
section.Get("ItemStyleBg", &info.uItemStyleBg);
section.Get("ItemFocusedStyleFg", &info.uItemFocusedStyleFg);
section.Get("ItemFocusedStyleBg", &info.uItemFocusedStyleBg);
section.Get("ItemDownStyleFg", &info.uItemDownStyleFg);
section.Get("ItemDownStyleBg", &info.uItemDownStyleBg);
section.Get("ItemDisabledStyleFg", &info.uItemDisabledStyleFg);
section.Get("ItemDisabledStyleBg", &info.uItemDisabledStyleBg);
section.Get("HeaderStyleFg", &info.uHeaderStyleFg, info.uHeaderStyleFg);
section.Get("HeaderStyleBg", &info.uHeaderStyleBg, info.uHeaderStyleBg);
section.Get("InfoStyleFg", &info.uInfoStyleFg, info.uInfoStyleFg);
section.Get("InfoStyleBg", &info.uInfoStyleBg, info.uInfoStyleBg);
section.Get("PopupStyleFg", &info.uPopupStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("PopupStyleBg", &info.uPopupStyleBg, info.uPopupStyleBg);
section.Get("TooltipStyleFg", &info.uTooltipStyleFg, info.uTooltipStyleFg); // Backwards compat
section.Get("TooltipStyleBg", &info.uTooltipStyleBg, info.uTooltipStyleBg);
section.Get("PopupTitleStyleFg", &info.uPopupTitleStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("PopupTitleStyleBg", &info.uPopupTitleStyleBg, info.uPopupTitleStyleBg);
section.Get("CollapsibleHeaderStyleFg", &info.uCollapsibleHeaderStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("CollapsibleHeaderStyleBg", &info.uCollapsibleHeaderStyleBg, info.uItemStyleBg);
section.Get("BackgroundColor", &info.uBackgroundColor, info.uBackgroundColor);
section.Get("ScrollbarColor", &info.uScrollbarColor, info.uScrollbarColor);
section.Get("PopupSliderColor", &info.uPopupSliderColor, info.uPopupSliderColor);
section.Get("PopupSliderFocusedColor", &info.uPopupSliderFocusedColor, info.uPopupSliderFocusedColor);
section.Get("HeaderStyleFg", &info.uHeaderStyleFg);
section.Get("HeaderStyleBg", &info.uHeaderStyleBg);
section.Get("InfoStyleFg", &info.uInfoStyleFg);
section.Get("InfoStyleBg", &info.uInfoStyleBg);
section.Get("PopupStyleFg", &info.uPopupStyleFg); // Backwards compat
section.Get("PopupStyleBg", &info.uPopupStyleBg);
section.Get("TooltipStyleFg", &info.uTooltipStyleFg); // Backwards compat
section.Get("TooltipStyleBg", &info.uTooltipStyleBg);
info.uPopupTitleStyleFg = info.uItemStyleFg;
section.Get("PopupTitleStyleFg", &info.uPopupTitleStyleFg);
section.Get("PopupTitleStyleBg", &info.uPopupTitleStyleBg);
info.uCollapsibleHeaderStyleFg = info.uInfoStyleFg;
info.uCollapsibleHeaderStyleBg = info.uInfoStyleBg;
section.Get("CollapsibleHeaderStyleFg", &info.uCollapsibleHeaderStyleFg); // Backwards compat
section.Get("CollapsibleHeaderStyleBg", &info.uCollapsibleHeaderStyleBg);
section.Get("BackgroundColor", &info.uBackgroundColor);
section.Get("ScrollbarColor", &info.uScrollbarColor);
section.Get("PopupSliderColor", &info.uPopupSliderColor);
section.Get("PopupSliderFocusedColor", &info.uPopupSliderFocusedColor);
appendTheme(info);
}