bgfx_entry_uniform* entry_uniform_reader::read_from_value(const Value& value, std::string prefix, bgfx_effect* effect, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params) { if (!validate_parameters(value, prefix)) { return nullptr; } std::string name = value["uniform"].GetString(); bgfx_uniform* uniform = effect->uniform(name); if (!READER_CHECK(uniform != nullptr, (prefix + "Uniform '" + name + " does not appear to exist\n").c_str())) { return nullptr; } if (value.HasMember("slider")) { return slider_uniform_reader::read_from_value(value, prefix, uniform, sliders); } else if (value.HasMember("value")) { return value_uniform_reader::read_from_value(value, prefix, uniform); } else if (value.HasMember("parameter")) { return param_uniform_reader::read_from_value(value, prefix, uniform, params); } else { READER_CHECK(false, (prefix + "Unrecognized uniform type for uniform binding " + name).c_str()); } return nullptr; }
bool suppressor_reader::validate_parameters(const Value& value, std::string prefix) { if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false; if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("value"), (prefix + "Must have numeric or array value 'value'\n").c_str())) return false; if (!READER_CHECK(value["value"].IsNumber() || value["value"].IsArray(), (prefix + "Value 'value' must be a number or array the size of the corresponding slider type\n").c_str())) return false; return true; }
bool effect_reader::validate_parameters(const Value& value, std::string prefix) { if (!READER_CHECK(value.HasMember("depth"), (prefix + "Must have object value 'depth' (what are our Z-buffer settings?)\n").c_str())) return false; if (!READER_CHECK(value.HasMember("cull"), (prefix + "Must have object value 'cull' (do we cull triangles based on winding?)\n").c_str())) return false; if (!READER_CHECK(value.HasMember("write"), (prefix + "Must have object value 'write' (what are our color buffer write settings?)\n").c_str())) return false; if (!READER_CHECK(value.HasMember("vertex"), (prefix + "Must have string value 'vertex' (what is our vertex shader?)\n").c_str())) return false; if (!READER_CHECK(value["vertex"].IsString(), (prefix + "Value 'vertex' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("fragment") || value.HasMember("pixel"), (prefix + "Must have string value named 'fragment' or 'pixel' (what is our fragment/pixel shader?)\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("fragment") || value["fragment"].IsString(), (prefix + "Value 'fragment' must be a string\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("pixel") || value["pixel"].IsString(), (prefix + "Value 'pixel' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("uniforms"), (prefix + "Must have array value 'uniforms' (what are our shader's parameters?)\n").c_str())) return false; if (!READER_CHECK(value["uniforms"].IsArray(), (prefix + "Value 'uniforms' must be an array\n").c_str())) return false; return true; }
bool chain_reader::validate_parameters(const Value& value, std::string prefix) { if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false; if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("author"), (prefix + "Must have string value 'author'\n").c_str())) return false; if (!READER_CHECK(value["author"].IsString(), (prefix + "Value 'author' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("passes"), (prefix + "Must have array value 'passes'\n").c_str())) return false; if (!READER_CHECK(value["passes"].IsArray(), (prefix + "Value 'passes' must be an array\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("sliders") || value["sliders"].IsArray(), (prefix + "Value 'sliders' must be an array\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("parameters") || value["parameters"].IsArray(), (prefix + "Value 'parameters' must be an array\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("targets") || value["targets"].IsArray(), (prefix + "Value 'targets' must be an array\n").c_str())) return false; return true; }
bool chain_entry_reader::validate_parameters(const Value& value, std::string prefix) { if (!READER_CHECK(value.HasMember("effect"), (prefix + "Must have string value 'effect' (what effect does this entry use?)\n").c_str())) return false; if (!READER_CHECK(value["effect"].IsString(), (prefix + "Value 'effect' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'effect' (what effect does this entry use?)\n").c_str())) return false; if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false; if (!READER_CHECK(value.HasMember("output"), (prefix + "Must have string value 'offset' (what target are we rendering to?)\n").c_str())) return false; if (!READER_CHECK(value["output"].IsString(), (prefix + "Value 'output' must be a string\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("input") || value["input"].IsArray(), (prefix + "Value 'input' must be an array\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("uniforms") || value["uniforms"].IsArray(), (prefix + "Value 'uniforms' must be an array\n").c_str())) return false; if (!READER_CHECK(!value.HasMember("disablewhen") || value["disablewhen"].IsArray(), (prefix + "Value 'disablewhen' must be an array\n").c_str())) return false; return true; }
bool suppressor_reader::get_values(const Value& value, std::string prefix, std::string name, int* values, const int count) { const char* name_str = name.c_str(); const Value& value_array = value[name_str]; for (uint32_t i = 0; i < value_array.Size() && i < count; i++) { if (!READER_CHECK(value_array[i].IsInt(), (prefix + "value[" + std::to_string(i) + "] must be an integer\n").c_str())) return false; values[i] = value_array[i].GetInt(); } return true; }
bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::string prefix, std::map<std::string, bgfx_slider*>& sliders) { if (!validate_parameters(value, prefix)) { return nullptr; } std::string name = value["name"].GetString(); uint32_t condition = uint32_t(get_enum_from_value(value, "condition", bgfx_suppressor::condition_type::CONDITION_EQUAL, CONDITION_NAMES, CONDITION_COUNT)); bgfx_suppressor::combine_mode mode = bgfx_suppressor::combine_mode(get_enum_from_value(value, "combine", bgfx_suppressor::combine_mode::COMBINE_OR, COMBINE_NAMES, COMBINE_COUNT)); std::vector<bgfx_slider*> check_sliders; check_sliders.push_back(sliders[name + "0"]); int slider_count; switch (check_sliders[0]->type()) { case bgfx_slider::slider_type::SLIDER_FLOAT: case bgfx_slider::slider_type::SLIDER_INT: case bgfx_slider::slider_type::SLIDER_INT_ENUM: slider_count = 1; break; case bgfx_slider::slider_type::SLIDER_VEC2: slider_count = 2; break; case bgfx_slider::slider_type::SLIDER_COLOR: slider_count = 3; break; default: slider_count = 0; break; } int values[4]; if (slider_count > 1) { get_values(value, prefix, "value", values, slider_count); if (!READER_CHECK(slider_count == value["value"].GetArray().Size(), (prefix + "Expected " + std::to_string(slider_count) + " values, got " + std::to_string(value["value"].GetArray().Size()) + "\n").c_str())) return nullptr; for (int index = 1; index < slider_count; index++) { check_sliders.push_back(sliders[name + std::to_string(index)]); } } else { values[0] = get_int(value, "value", 0); } return new bgfx_suppressor(check_sliders, condition, mode, values); }
std::wstring sqlite3_cursor::getstring16(int index) { READER_CHECK(wstring); return std::wstring((const wchar_t*)sqlite3_column_text16(this->cmd->stmt, index), sqlite3_column_bytes16(this->cmd->stmt, index)/2); }
bool entry_uniform_reader::validate_parameters(const Value& value, std::string prefix) { if (!READER_CHECK(value.HasMember("uniform"), (prefix + "Must have string value 'uniform' (what uniform are we mapping?)\n").c_str())) return false; if (!READER_CHECK(value["uniform"].IsString(), (prefix + "Value 'effect' must be a string\n").c_str())) return false; return true; }
int sqlite3_cursor::getint(int index) { READER_CHECK(getint); return sqlite3_column_int(this->cmd->stmt, index); }
bool sqlite3_cursor::isnull(int index) { READER_CHECK(isnull); return sqlite3_column_type(this->cmd->stmt, index) == SQLITE_NULL; }
std::wstring sqlite3_cursor::getcolname16(int index) { READER_CHECK(wstring); return (const wchar_t*)sqlite3_column_name16(this->cmd->stmt, index); }
std::string sqlite3_cursor::getcolname(int index) { READER_CHECK(string); char const * cn = sqlite3_column_name(this->cmd->stmt, index); return cn ? cn : ""; }
void const * sqlite3_cursor::getblob(int index, int & size ) { READER_CHECK(string); size = sqlite3_column_bytes(this->cmd->stmt, index); return sqlite3_column_blob(this->cmd->stmt, index); }
std::string sqlite3_cursor::getblob(int index) { READER_CHECK(string); return std::string((const char*)sqlite3_column_blob(this->cmd->stmt, index), sqlite3_column_bytes(this->cmd->stmt, index)); }
bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index) { if (!validate_parameters(value, prefix)) { printf("Failed validation\n"); return nullptr; } bgfx_effect* effect = chains.effects().effect(value["effect"].GetString()); if (effect == nullptr) { return nullptr; } std::string name = value["name"].GetString(); std::vector<bgfx_input_pair*> inputs; if (value.HasMember("input")) { const Value& input_array = value["input"]; for (uint32_t i = 0; i < input_array.Size(); i++) { const Value& input = input_array[i]; if (!READER_CHECK(input.HasMember("sampler"), (prefix + "input[" + std::to_string(i) + ": Must have string value 'sampler' (what sampler are we binding to?)\n").c_str())) return nullptr; if (!READER_CHECK(input["sampler"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'sampler' must be a string\n").c_str())) return nullptr; bool has_texture = input.HasMember("texture"); bool has_target = input.HasMember("target"); bool has_option = input.HasMember("option"); if (!READER_CHECK(has_texture || has_target || has_option, (prefix + "input[" + std::to_string(i) + ": Must have string value 'target', 'texture' or 'option' (what source are we using?)\n").c_str())) return nullptr; if (!READER_CHECK(!has_texture || input["texture"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'texture' must be a string\n").c_str())) return nullptr; if (!READER_CHECK(!has_target || input["target"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'target' must be a string\n").c_str())) return nullptr; if (!READER_CHECK(!has_option || input["option"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'option' must be a string\n").c_str())) return nullptr; if (!READER_CHECK(has_target || !input.HasMember("bilinear") || input["bilinear"].IsBool(), (prefix + "input[" + std::to_string(i) + ": Value 'bilinear' must be a boolean\n").c_str())) return nullptr; if (!READER_CHECK(has_target || !input.HasMember("clamp") || input["clamp"].IsBool(), (prefix + "input[" + std::to_string(i) + ": Value 'clamp' must be a boolean\n").c_str())) return nullptr; if (!READER_CHECK(has_texture || has_option || !input.HasMember("selection") || input["selection"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'selection' must be a string\n").c_str())) return nullptr; bool bilinear = get_bool(input, "bilinear", true); bool clamp = get_bool(input, "clamp", false); std::string selection = get_string(input, "selection", ""); std::vector<std::string> texture_names; std::string texture_name = ""; if (has_texture || has_option) { if (has_texture) { texture_name = input["texture"].GetString(); } if (has_option) { std::string option = input["option"].GetString(); texture_name = chains.options().value(option.c_str()); } if (texture_name != "" && texture_name != "screen") { if (selection == "") { // create texture for specified file name uint32_t flags = bilinear ? 0u : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT); flags |= clamp ? (BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP) : 0u; bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), texture_name, texture_name, flags, screen_index); if (texture == nullptr) { return nullptr; } } else { // create texture for specified file name uint32_t flags = bilinear ? 0u : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT); flags |= clamp ? (BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP) : 0u; bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), texture_name, texture_name, flags, screen_index); if (texture == nullptr) { return nullptr; } // get directory of file std::string directory_path = std::string(chains.options().art_path()); std::string file_directory = ""; const size_t last_slash = texture_name.rfind('/'); if (last_slash != std::string::npos) { file_directory = texture_name.substr(0, last_slash); directory_path += "/" + file_directory; } osd::directory::ptr directory = osd::directory::open(directory_path); if (directory) { for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read()) { if (entry->type == osd::directory::entry::entry_type::FILE) { std::string file(entry->name); std::string extension(".png"); // split into file name and extension std::string file_name; std::string file_extension; const size_t last_dot = file.rfind('.'); if (last_dot != std::string::npos) { file_name = file.substr(0, last_dot); file_extension = file.substr(last_dot, file.length() - last_dot); } std::string file_path; if (file_directory == "") { file_path = file; } else { file_path = file_directory + "/" + file; } // check for .png extension if (file_extension == extension) { // create textures for all files containd in the path of the specified file name uint32_t flags = bilinear ? 0u : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT); flags |= clamp ? (BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_W_CLAMP) : 0u; bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), file_path, file_path, flags, screen_index); if (texture == nullptr) { return nullptr; } texture_names.push_back(file_path); } } } } } } } else if (has_target) { texture_name = input["target"].GetString(); } else { return nullptr; } std::string sampler = input["sampler"].GetString(); bgfx_input_pair* input_pair = new bgfx_input_pair(i, sampler, texture_name, texture_names, selection, chains, screen_index); inputs.push_back(input_pair); } } std::vector<bgfx_entry_uniform*> uniforms; if (value.HasMember("uniforms")) { const Value& uniform_array = value["uniforms"]; for (uint32_t i = 0; i < uniform_array.Size(); i++) { bgfx_entry_uniform* uniform = entry_uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ", effect, sliders, params); if (uniform == nullptr) { for (bgfx_entry_uniform* existing_uniform : uniforms) delete existing_uniform; return nullptr; } uniforms.push_back(uniform); } } std::vector<bgfx_suppressor*> suppressors; if (value.HasMember("disablewhen")) { const Value& suppressor_array = value["disablewhen"]; for (uint32_t i = 0; i < suppressor_array.Size(); i++) { bgfx_suppressor* suppressor = suppressor_reader::read_from_value(suppressor_array[i], prefix, sliders); if (suppressor == nullptr) { for (bgfx_entry_uniform* uniform : uniforms) delete uniform; for (bgfx_suppressor* existing_suppressor : suppressors) delete existing_suppressor; return nullptr; } suppressors.push_back(suppressor); } } // Parse clear state clear_state* clear = nullptr; if (value.HasMember("clear")) { clear = clear_reader::read_from_value(value["clear"], prefix + "clear state: "); } else { clear = new clear_state(BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0); } std::string output = value["output"].GetString(); return new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, chains.targets(), output); }
char const * sqlite3_cursor::getstring(int index, int & size) { READER_CHECK(string); size = sqlite3_column_bytes(this->cmd->stmt, index); return (char const *)sqlite3_column_text(this->cmd->stmt, index); }
double sqlite3_cursor::getdouble(int index) { READER_CHECK(getdouble); return sqlite3_column_double(this->cmd->stmt, index); }