From 6bdc32c54aa19b8b61b19a4b11167ba329667b0a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 29 Jul 2014 11:47:56 -0500 Subject: Add the VideoCommon PostProcessing class. This class loads all the common PP shader configuration options and passes those options through to a inherited class that OpenGL or D3D will have. Makes it so all the common code for PP shaders is in VideoCommon instead of duplicating the code across each backend. --- Source/Core/VideoCommon/PostProcessing.cpp | 304 +++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 Source/Core/VideoCommon/PostProcessing.cpp (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp new file mode 100644 index 0000000000..019001da15 --- /dev/null +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -0,0 +1,304 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include + +#include "Common/CommonPaths.h" +#include "Common/FileUtil.h" +#include "Common/IniFile.h" +#include "Common/StringUtil.h" + +#include "VideoCommon/PostProcessing.h" +#include "VideoCommon/VideoConfig.h" + + +PostProcessingShaderImplementation::PostProcessingShaderImplementation() +{ + m_timer.Start(); +} + +PostProcessingShaderImplementation::~PostProcessingShaderImplementation() +{ + m_timer.Stop(); +} + +std::string PostProcessingShaderConfiguration::LoadShader(std::string shader) +{ + // Load the shader from the configuration if there isn't one sent to us. + if (shader == "") + shader = g_ActiveConfig.sPostProcessingShader; + m_current_shader = shader; + + // loading shader code + std::string code; + std::string path = File::GetUserPath(D_SHADERS_IDX) + shader + ".glsl"; + + if (!File::Exists(path)) + { + // Fallback to shared user dir + path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + shader + ".glsl"; + } + + if (!File::ReadFileToString(path, code)) + { + ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str()); + return ""; + } + + LoadOptions(code); + LoadOptionsConfiguration(); + + return code; +} + +void PostProcessingShaderConfiguration::LoadOptions(const std::string& code) +{ + const std::string config_start_delimiter = "[configuration]"; + const std::string config_end_delimiter = "[/configuration]"; + size_t configuration_start = code.find(config_start_delimiter); + size_t configuration_end = code.find(config_end_delimiter); + + m_options.clear(); + m_any_options_dirty = true; + + if (configuration_start == std::string::npos || + configuration_end == std::string::npos) + { + // Issue loading configuration or there isn't one. + return; + } + + std::string configuration_string = code.substr(configuration_start + config_start_delimiter.size(), + configuration_end - configuration_start - config_start_delimiter.size()); + + std::istringstream in(configuration_string); + + struct GLSLStringOption + { + std::string m_type; + std::vector> m_options; + }; + + std::vector option_strings; + GLSLStringOption* current_strings = nullptr; + while (!in.eof()) + { + std::string line; + + if (std::getline(in, line)) + { +#ifndef _WIN32 + // Check for CRLF eol and convert it to LF + if (!line.empty() && line.at(line.size()-1) == '\r') + { + line.erase(line.size()-1); + } +#endif + + if (line.size() > 0) + { + if (line[0] == '[') + { + size_t endpos = line.find("]"); + + if (endpos != std::string::npos) + { + // New section! + std::string sub = line.substr(1, endpos - 1); + option_strings.push_back({ sub }); + current_strings = &option_strings.back(); + } + } + else + { + if (current_strings) + { + std::string key, value; + IniFile::ParseLine(line, &key, &value); + + if (!(key == "" && value == "")) + current_strings->m_options.push_back(std::make_pair(key, value)); + } + } + } + } + } + + for (const auto& it : option_strings) + { + ConfigurationOption option; + option.m_dirty = true; + + if (it.m_type == "OptionBool") + option.m_type = ConfigurationOption::OptionType::OPTION_BOOL; + else if (it.m_type == "OptionRangeFloat") + option.m_type = ConfigurationOption::OptionType::OPTION_FLOAT; + else if (it.m_type == "OptionRangeInteger") + option.m_type = ConfigurationOption::OptionType::OPTION_INTEGER; + + for (const auto& string_option : it.m_options) + { + if (string_option.first == "GUIName") + { + option.m_gui_name = string_option.second; + } + else if (string_option.first == "OptionName") + { + option.m_option_name = string_option.second; + } + else if (string_option.first == "DependentOption") + { + option.m_dependent_option = string_option.second; + } + else if (string_option.first == "MinValue" || + string_option.first == "MaxValue" || + string_option.first == "DefaultValue" || + string_option.first == "StepAmount") + { + std::vector* output_integer = nullptr; + std::vector* output_float = nullptr; + + if (string_option.first == "MinValue") + { + output_integer = &option.m_integer_min_values; + output_float = &option.m_float_min_values; + } + else if (string_option.first == "MaxValue") + { + output_integer = &option.m_integer_max_values; + output_float = &option.m_float_max_values; + } + else if (string_option.first == "DefaultValue") + { + output_integer = &option.m_integer_values; + output_float = &option.m_float_values; + } + else if (string_option.first == "StepAmount") + { + output_integer = &option.m_integer_step_values; + output_float = &option.m_float_step_values; + } + + if (option.m_type == ConfigurationOption::OptionType::OPTION_BOOL) + { + TryParse(string_option.second, &option.m_bool_value); + } + else if (option.m_type == ConfigurationOption::OptionType::OPTION_INTEGER) + { + TryParseVector(string_option.second, output_integer); + if (output_integer->size() > 4) + output_integer->erase(output_integer->begin() + 4, output_integer->end()); + } + else if (option.m_type == ConfigurationOption::OptionType::OPTION_FLOAT) + { + TryParseVector(string_option.second, output_float); + if (output_float->size() > 4) + output_float->erase(output_float->begin() + 4, output_float->end()); + } + } + } + m_options[option.m_option_name] = option; + } +} + +void PostProcessingShaderConfiguration::LoadOptionsConfiguration() +{ + IniFile ini; + ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); + std::string section = m_current_shader + "-options"; + + for (auto& it : m_options) + { + switch (it.second.m_type) + { + case ConfigurationOption::OptionType::OPTION_BOOL: + ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &it.second.m_bool_value, it.second.m_bool_value); + break; + case ConfigurationOption::OptionType::OPTION_INTEGER: + { + std::string value; + ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &value); + if (value != "") + TryParseVector(value, &it.second.m_integer_values); + } + break; + case ConfigurationOption::OptionType::OPTION_FLOAT: + { + std::string value; + ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &value); + if (value != "") + TryParseVector(value, &it.second.m_float_values); + } + break; + } + } +} + +void PostProcessingShaderConfiguration::SaveOptionsConfiguration() +{ + IniFile ini; + ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); + std::string section = m_current_shader + "-options"; + + for (auto& it : m_options) + { + switch (it.second.m_type) + { + case ConfigurationOption::OptionType::OPTION_BOOL: + { + ini.GetOrCreateSection(section)->Set(it.second.m_option_name, it.second.m_bool_value); + } + break; + case ConfigurationOption::OptionType::OPTION_INTEGER: + { + std::string value = ""; + for (size_t i = 0; i < it.second.m_integer_values.size(); ++i) + value += StringFromFormat("%d%s", it.second.m_integer_values[i], i == (it.second.m_integer_values.size() - 1) ? "": ", "); + ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value); + } + break; + case ConfigurationOption::OptionType::OPTION_FLOAT: + { + std::string value = ""; + for (size_t i = 0; i < it.second.m_float_values.size(); ++i) + value += StringFromFormat("%f%s", it.second.m_float_values[i], i == (it.second.m_float_values.size() - 1) ? "": ", "); + ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value); + } + break; + } + } + ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX)); +} + +void PostProcessingShaderConfiguration::ReloadShader() +{ + m_current_shader = ""; +} + +void PostProcessingShaderConfiguration::SetOptionf(std::string option, int index, float value) +{ + auto it = m_options.find(option); + + it->second.m_float_values[index] = value; + it->second.m_dirty = true; + m_any_options_dirty = true; +} + +void PostProcessingShaderConfiguration::SetOptioni(std::string option, int index, s32 value) +{ + auto it = m_options.find(option); + + it->second.m_integer_values[index] = value; + it->second.m_dirty = true; + m_any_options_dirty = true; +} + +void PostProcessingShaderConfiguration::SetOptionb(std::string option, bool value) +{ + auto it = m_options.find(option); + + it->second.m_bool_value = value; + it->second.m_dirty = true; + m_any_options_dirty = true; +} -- cgit v1.2.3 From 2d624780c05ecfee62bcf3c04d35e767063fac5a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 17 Aug 2014 22:57:39 -0500 Subject: 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 --- Source/Core/VideoCommon/PostProcessing.cpp | 128 +++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') 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)); -- cgit v1.2.3 From bf93920c05c055eed2fb8eadd38f2b7a3a244187 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Mon, 25 Aug 2014 14:33:41 +0200 Subject: Revert "Catch broken configurations inside of the Post Processing shaders." --- Source/Core/VideoCommon/PostProcessing.cpp | 128 ----------------------------- 1 file changed, 128 deletions(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 69d34dbe66..019001da15 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -7,7 +7,6 @@ #include "Common/CommonPaths.h" #include "Common/FileUtil.h" #include "Common/IniFile.h" -#include "Common/MsgHandler.h" #include "Common/StringUtil.h" #include "VideoCommon/PostProcessing.h" @@ -48,132 +47,11 @@ 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]"; @@ -258,8 +136,6 @@ 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) { @@ -355,8 +231,6 @@ void PostProcessingShaderConfiguration::LoadOptionsConfiguration() TryParseVector(value, &it.second.m_float_values); } break; - case ConfigurationOption::OptionType::OPTION_INVALID: // Won't get hit - break; } } } @@ -392,8 +266,6 @@ 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)); -- cgit v1.2.3 From d348bfea46120ee79ccdf859805263bdab2f11c6 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 20 Jan 2015 16:40:46 -0600 Subject: Fix the Post Processing shader configuration dialog. On locales that don't use period as a separator this would break us. For vector values in a configuration, we use comma as a separator which causes the configuration to balloon to massive sizes due to never saving them correctly. Loading would then break since it would load a million configuration options. Fixes issue #7569. --- Source/Core/VideoCommon/PostProcessing.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 019001da15..b4ee1e8702 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -260,10 +260,16 @@ void PostProcessingShaderConfiguration::SaveOptionsConfiguration() break; case ConfigurationOption::OptionType::OPTION_FLOAT: { - std::string value = ""; + std::ostringstream value; + value.imbue(std::locale("C")); + for (size_t i = 0; i < it.second.m_float_values.size(); ++i) - value += StringFromFormat("%f%s", it.second.m_float_values[i], i == (it.second.m_float_values.size() - 1) ? "": ", "); - ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value); + { + value << it.second.m_float_values[i]; + if (i != (it.second.m_float_values.size() - 1)) + value << ", "; + } + ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value.str()); } break; } -- cgit v1.2.3 From 262c3b19ecf9a4c022b3667613f892a5539dd34d Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 3 Jan 2015 01:33:30 +0100 Subject: PostProcessing: Add support for user-supplied anaglyph shaders. There are lots of different anaglyph glasses out there and there may be even more creative uses for stereoscopic post-processing shaders. --- Source/Core/VideoCommon/PostProcessing.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index b4ee1e8702..c27b0f89fc 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -30,14 +30,16 @@ std::string PostProcessingShaderConfiguration::LoadShader(std::string shader) shader = g_ActiveConfig.sPostProcessingShader; m_current_shader = shader; + const std::string sub_dir = (g_Config.iStereoMode == STEREO_ANAGLYPH) ? ANAGLYPH_DIR DIR_SEP : ""; + // loading shader code std::string code; - std::string path = File::GetUserPath(D_SHADERS_IDX) + shader + ".glsl"; + std::string path = File::GetUserPath(D_SHADERS_IDX) + sub_dir + shader + ".glsl"; if (!File::Exists(path)) { // Fallback to shared user dir - path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + shader + ".glsl"; + path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + sub_dir + shader + ".glsl"; } if (!File::ReadFileToString(path, code)) -- cgit v1.2.3 From 5c4ee2f71e2e1c80ba2bf829751f1202f6e65ee9 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 25 Jan 2015 23:08:49 +0100 Subject: PostProcessing: Move default pixel shader to PostProcessingShaderConfiguration. Reduces code complexity and fixes a bug where the shader is not properly invalidated. --- Source/Core/VideoCommon/PostProcessing.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index c27b0f89fc..c299d41b15 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -13,6 +13,8 @@ #include "VideoCommon/VideoConfig.h" +static const char s_default_shader[] = "void main() { SetOutput(Sample()); }\n"; + PostProcessingShaderImplementation::PostProcessingShaderImplementation() { m_timer.Start(); @@ -36,16 +38,23 @@ std::string PostProcessingShaderConfiguration::LoadShader(std::string shader) std::string code; std::string path = File::GetUserPath(D_SHADERS_IDX) + sub_dir + shader + ".glsl"; - if (!File::Exists(path)) + if (shader == "") { - // Fallback to shared user dir - path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + sub_dir + shader + ".glsl"; + code = s_default_shader; } - - if (!File::ReadFileToString(path, code)) + else { - ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str()); - return ""; + if (!File::Exists(path)) + { + // Fallback to shared user dir + path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + sub_dir + shader + ".glsl"; + } + + if (!File::ReadFileToString(path, code)) + { + ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str()); + code = s_default_shader; + } } LoadOptions(code); -- cgit v1.2.3 From e07679114bf33e387c2d4094cac3174650def0e5 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 4 Feb 2015 10:36:42 -0500 Subject: Use emplace_* functions where in-place construction is preferable --- Source/Core/VideoCommon/PostProcessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index c299d41b15..2d4290fbe6 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -129,7 +129,7 @@ void PostProcessingShaderConfiguration::LoadOptions(const std::string& code) IniFile::ParseLine(line, &key, &value); if (!(key == "" && value == "")) - current_strings->m_options.push_back(std::make_pair(key, value)); + current_strings->m_options.emplace_back(key, value); } } } -- cgit v1.2.3 From cefcb0ace9d363b3679b4e93bcc9ec05f1e5f4f8 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Mon, 18 May 2015 01:08:10 +0200 Subject: Update license headers to GPLv2+ --- Source/Core/VideoCommon/PostProcessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 2d4290fbe6..53aa724761 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -1,5 +1,5 @@ // Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2+ // Refer to the license.txt file included. #include -- cgit v1.2.3 From 30ebb2459eb97ba544547183854775df8460b475 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 24 May 2015 06:55:12 +0200 Subject: Set copyright year to when a file was created --- Source/Core/VideoCommon/PostProcessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 53aa724761..3841bbfd4f 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -1,4 +1,4 @@ -// Copyright 2013 Dolphin Emulator Project +// Copyright 2014 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. -- cgit v1.2.3 From ac26f8e79fbf640ba770a35c1f051c2816f6346f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 28 May 2015 20:28:48 -0400 Subject: Pass strings by const reference where possible --- Source/Core/VideoCommon/PostProcessing.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/PostProcessing.cpp') diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index 3841bbfd4f..1ee7e142dd 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -293,7 +293,7 @@ void PostProcessingShaderConfiguration::ReloadShader() m_current_shader = ""; } -void PostProcessingShaderConfiguration::SetOptionf(std::string option, int index, float value) +void PostProcessingShaderConfiguration::SetOptionf(const std::string& option, int index, float value) { auto it = m_options.find(option); @@ -302,7 +302,7 @@ void PostProcessingShaderConfiguration::SetOptionf(std::string option, int index m_any_options_dirty = true; } -void PostProcessingShaderConfiguration::SetOptioni(std::string option, int index, s32 value) +void PostProcessingShaderConfiguration::SetOptioni(const std::string& option, int index, s32 value) { auto it = m_options.find(option); @@ -311,7 +311,7 @@ void PostProcessingShaderConfiguration::SetOptioni(std::string option, int index m_any_options_dirty = true; } -void PostProcessingShaderConfiguration::SetOptionb(std::string option, bool value) +void PostProcessingShaderConfiguration::SetOptionb(const std::string& option, bool value) { auto it = m_options.find(option); -- cgit v1.2.3