diff options
| author | Ryan Houdek <Sonicadvance1@gmail.com> | 2014-08-17 22:57:39 -0500 |
|---|---|---|
| committer | Ryan Houdek <Sonicadvance1@gmail.com> | 2014-08-17 23:59:21 -0500 |
| commit | 2d624780c05ecfee62bcf3c04d35e767063fac5a (patch) | |
| tree | 6bb54661d831bc7b30d50f8cdbe11f22a6dca19f /Source/Core/VideoCommon/PostProcessing.cpp | |
| parent | 9e2fbaf40551b6d037a94274433b03c580dc1604 (diff) | |
Catch broken configurations inside of the Post Processing shaders.
This catches most instances of configuration failures that can happen in a post processing shader.
Gives a user a helpful error message that lets them know what they have failed to set up correctly
Diffstat (limited to 'Source/Core/VideoCommon/PostProcessing.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/PostProcessing.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 019001da15..69d34dbe66 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -7,6 +7,7 @@ #include "Common/CommonPaths.h" #include "Common/FileUtil.h" #include "Common/IniFile.h" +#include "Common/MsgHandler.h" #include "Common/StringUtil.h" #include "VideoCommon/PostProcessing.h" @@ -47,11 +48,132 @@ std::string PostProcessingShaderConfiguration::LoadShader(std::string shader) } LoadOptions(code); + + std::string error = VerifyOptions(m_options); + if (error.size()) + { + PanicAlert("%s", StringFromFormat("Shader %s has a configuration issue!\n%s", shader.c_str(), error.c_str()).c_str()); + return ""; + } + LoadOptionsConfiguration(); return code; } +std::string PostProcessingShaderConfiguration::VerifyOptions(const ConfigMap& config_map) +{ + for (const auto& option : config_map) + { + // Make sure we have an option name + if (!option.second.m_option_name.size()) + return "Option doesn't have a unique identifier via 'OptionName'"; + + // Make sure we have a correct type + if (option.second.m_type == ConfigurationOption::OptionType::OPTION_INVALID) + return StringFromFormat("Option '%s' has invalid type", option.second.m_option_name.c_str()); + + // Make sure we have a GUI name + if (!option.second.m_gui_name.size()) + return StringFromFormat("Option '%s' has no GUI name", option.second.m_option_name.c_str()); + + // If we have a dependent option, make sure that option actually exists + if (option.second.m_dependent_option.size()) + { + if (config_map.find(option.second.m_dependent_option) == config_map.end()) + return StringFromFormat("Option '%s' has a dependent option '%s' that doesn't exist", + option.second.m_option_name.c_str(), option.second.m_dependent_option.c_str()); + } + + switch (option.second.m_type) + { + case ConfigurationOption::OptionType::OPTION_INTEGER: + { + // Make sure our vectors are the same sizes + if (option.second.m_integer_values.size() != option.second.m_integer_min_values.size() || + option.second.m_integer_min_values.size() != option.second.m_integer_max_values.size() || + option.second.m_integer_max_values.size() != option.second.m_integer_step_values.size()) + return StringFromFormat("Option '%s' has invalid set value amounts", option.second.m_option_name.c_str()); + + int option_size = option.second.m_integer_values.size(); + // Make sure our minimums are lower than our maximums + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_integer_min_values[i] > option.second.m_integer_max_values[i]) + return StringFromFormat("Option '%s' minimum value index %d is greater than max(%d > %d)", + option.second.m_option_name.c_str(), i, + option.second.m_integer_min_values[i], option.second.m_integer_max_values[i]); + } + + // Make sure the default value is between minimum and maximum + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_integer_values[i] < option.second.m_integer_min_values[i] || + option.second.m_integer_values[i] > option.second.m_integer_max_values[i]) + return StringFromFormat("Option '%s' default value index %d is outside of available range(%d outside %d - %d)", + option.second.m_option_name.c_str(), i, + option.second.m_integer_values[i], + option.second.m_integer_min_values[i], option.second.m_integer_max_values[i]); + } + + // Make sure our step size is smaller than the range acceptable values + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_integer_step_values[i] > + (option.second.m_integer_max_values[i] - option.second.m_integer_min_values[i])) + return StringFromFormat("Option '%s' step value is larger than maximum range of %d", + option.second.m_option_name.c_str(), option.second.m_integer_max_values[i] - option.second.m_integer_min_values[i]); + } + } + break; + case ConfigurationOption::OptionType::OPTION_FLOAT: + { + // Make sure our vectors are the same sizes + if (option.second.m_float_values.size() != option.second.m_float_min_values.size() || + option.second.m_float_min_values.size() != option.second.m_float_max_values.size() || + option.second.m_float_max_values.size() != option.second.m_float_step_values.size()) + return StringFromFormat("Option '%s' has invalid set value amounts", option.second.m_option_name.c_str()); + + int option_size = option.second.m_float_values.size(); + // Make sure our minimums are lower than our maximums + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_float_min_values[i] > option.second.m_float_max_values[i]) + return StringFromFormat("Option '%s' minimum value index %d is greater than max(%f > %f)", + option.second.m_option_name.c_str(), i, + option.second.m_float_min_values[i], option.second.m_float_max_values[i]); + } + + // Make sure the default value is between minimum and maximum + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_float_values[i] < option.second.m_float_min_values[i] || + option.second.m_float_values[i] > option.second.m_float_max_values[i]) + return StringFromFormat("Option '%s' default value index %d is outside of available range(%f outside %f - %f)", + option.second.m_option_name.c_str(), i, + option.second.m_float_values[i], + option.second.m_float_min_values[i], option.second.m_float_max_values[i]); + } + + // Make sure our step size is smaller than the range acceptable values + for (int i = 0; i < option_size; ++i) + { + if (option.second.m_float_step_values[i] > + (option.second.m_float_max_values[i] - option.second.m_float_min_values[i])) + return StringFromFormat("Option '%s' step value is larger than maximum range of %f", + option.second.m_option_name.c_str(), option.second.m_float_max_values[i] - option.second.m_float_min_values[i]); + } + } + break; + case ConfigurationOption::OptionType::OPTION_BOOL: + case ConfigurationOption::OptionType::OPTION_INVALID: // Won't be hit + default: + break; + } + } + return ""; +} + void PostProcessingShaderConfiguration::LoadOptions(const std::string& code) { const std::string config_start_delimiter = "[configuration]"; @@ -136,6 +258,8 @@ void PostProcessingShaderConfiguration::LoadOptions(const std::string& code) option.m_type = ConfigurationOption::OptionType::OPTION_FLOAT; else if (it.m_type == "OptionRangeInteger") option.m_type = ConfigurationOption::OptionType::OPTION_INTEGER; + else + option.m_type = ConfigurationOption::OptionType::OPTION_INVALID; for (const auto& string_option : it.m_options) { @@ -231,6 +355,8 @@ void PostProcessingShaderConfiguration::LoadOptionsConfiguration() TryParseVector(value, &it.second.m_float_values); } break; + case ConfigurationOption::OptionType::OPTION_INVALID: // Won't get hit + break; } } } @@ -266,6 +392,8 @@ void PostProcessingShaderConfiguration::SaveOptionsConfiguration() ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value); } break; + case ConfigurationOption::OptionType::OPTION_INVALID: // Won't get hit + break; } } ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX)); |
