summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PostProcessing.cpp
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-08-17 22:57:39 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2014-08-17 23:59:21 -0500
commit2d624780c05ecfee62bcf3c04d35e767063fac5a (patch)
tree6bb54661d831bc7b30d50f8cdbe11f22a6dca19f /Source/Core/VideoCommon/PostProcessing.cpp
parent9e2fbaf40551b6d037a94274433b03c580dc1604 (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.cpp128
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));