123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- // Copyright 2014 Dolphin Emulator Project
- // Licensed under GPLv2+
- // Refer to the license.txt file included.
- #include <string>
- #include "Common/CommonPaths.h"
- #include "Common/FileUtil.h"
- #include "Common/IniFile.h"
- #include "Common/StringUtil.h"
- #include "VideoCommon/PostProcessing.h"
- #include "VideoCommon/VideoConfig.h"
- static const char s_default_shader[] = "void main() { SetOutput(Sample()); }\n";
- 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;
- 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) + sub_dir + shader + ".glsl";
- if (shader == "")
- {
- code = s_default_shader;
- }
- else
- {
- 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);
- 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<std::pair<std::string, std::string>> m_options;
- };
- std::vector<GLSLStringOption> 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.emplace_back(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<s32>* output_integer = nullptr;
- std::vector<float>* 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::ostringstream value;
- value.imbue(std::locale("C"));
- for (size_t i = 0; i < it.second.m_float_values.size(); ++i)
- {
- 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;
- }
- }
- ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
- }
- void PostProcessingShaderConfiguration::ReloadShader()
- {
- m_current_shader = "";
- }
- void PostProcessingShaderConfiguration::SetOptionf(const 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(const 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(const 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;
- }
|