checkbox::checkbox(const variant& v, game_logic::formula_callable* e) : checked_(false), button(v,e) { hpadding_ = v["hpad"].as_int(12); if(v.has_key("padding")) { ASSERT_LOG(v["padding"].num_elements() == 2, "Incorrect number of padding elements specifed." << v["padding"].num_elements()); hpadding_ = v["padding"][0].as_int(); } checked_ = v["checked"].as_bool(false); variant label_var = v["label"]; label_ = (label_var.is_map() || label_var.is_callable()) ? "" : label_var.as_string_default("Checkbox"); label_widget_ = (label_var.is_map() || label_var.is_callable()) ? widget_factory::create(label_var, e) : widget_ptr(new graphical_font_label(label_, "door_label", 2)); ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); click_handler_ = get_environment()->create_formula(v["on_click"]); onclick_ = boost::bind(&checkbox::click, this, _1); set_click_handler(boost::bind(&checkbox::on_click, this)); set_label(create_checkbox_widget(label_widget_, checked_, button_resolution(), hpadding_)); if(v.has_key("width") || v.has_key("height")) { set_dim(v["width"].as_int(width()), v["height"].as_int(height())); } }
world::world(const variant& node) : view_distance_(node["view_distance"].as_int(default_view_distance)), seed_(node["seed"].as_int(0)) { ASSERT_LOG(node.has_key("shader"), "Must have 'shader' attribute"); ASSERT_LOG(node["shader"].is_string(), "'shader' attribute must be a string"); shader_ = gles2::shader_program::get_global(node["shader"].as_string())->shader(); if(node.has_key("lighting")) { lighting_.reset(new graphics::lighting(shader_, node["lighting"])); } if(node.has_key("objects")) { for(int n = 0; n != node["objects"].num_elements(); ++n) { add_object(new user_voxel_object(node["objects"][n])); } } if(node.has_key("skybox")) { skybox_.reset(new graphics::skybox(node["skybox"])); } if(node.has_key("chunks")) { logic_.reset(new logical_world(node)); build_fixed(node["chunks"]); } else { build_infinite(); } }
BlendEquation::BlendEquation(const variant& node) : rgb_(BlendEquationConstants::BE_ADD), alpha_(BlendEquationConstants::BE_ADD) { if(node.is_map()) { if(node.has_key("rgba")) { rgb_ = alpha_ = convert_string_to_equation(node["rgba"].as_string()); } if(node.has_key("rgb")) { rgb_ = convert_string_to_equation(node["rgb"].as_string()); } if(node.has_key("alpha")) { alpha_ = convert_string_to_equation(node["alpha"].as_string()); } if(node.has_key("a")) { alpha_ = convert_string_to_equation(node["a"].as_string()); } } else if(node.is_list()) { ASSERT_LOG(node.num_elements() > 0, "When using a list for blend equation must give at least one element"); if(node.num_elements() == 1) { rgb_ = alpha_ = convert_string_to_equation(node[0].as_string()); } else { rgb_ = convert_string_to_equation(node[0].as_string()); alpha_ = convert_string_to_equation(node[1].as_string()); } } else if(node.is_string()) { // simply setting the rgb/alpha values that same, from string rgb_ = alpha_ = convert_string_to_equation(node.as_string()); } else { ASSERT_LOG(false, "Unrecognised type for blend equation: " << node.to_debug_string()); } }
Model read_model(const variant& v) { Model model; if(v.has_key("feet")) { model.feet_position = read_voxel_pos(v["feet"]); } else { model.feet_position[0] = model.feet_position[1] = model.feet_position[2] = 0; } if(v.has_key("scale")) { model.scale = v["scale"].as_decimal(); } else { model.scale = decimal::from_int(1); } for(const std::pair<variant,variant>& p : v["layers"].as_map()) { LayerType layer_type = read_layer_type(p.second); layer_type.name = p.first.as_string(); model.layer_types.push_back(layer_type); } for(const std::pair<variant,variant>& p : v["animations"].as_map()) { Animation anim = read_animation(p.second); anim.name = p.first.as_string(); model.animations.push_back(anim); } if(v.has_key("attachment_points")) { model.attachment_points = read_attachment_points(v["attachment_points"]); } return model; }
frame::frame(variant node) : id_(node["id"].as_string()), image_(node["image"].as_string()), variant_id_(id_), enter_event_id_(get_object_event_id("enter_" + id_ + "_anim")), end_event_id_(get_object_event_id("end_" + id_ + "_anim")), leave_event_id_(get_object_event_id("leave_" + id_ + "_anim")), process_event_id_(get_object_event_id("process_" + id_)), texture_(node.has_key("fbo") ? node["fbo"].convert_to<texture_object>()->texture() : graphics::texture::get(image_, node["image_formula"].as_string_default())), solid_(solid_info::create(node)), collide_rect_(node.has_key("collide") ? rect(node["collide"]) : rect(node["collide_x"].as_int(), node["collide_y"].as_int(), node["collide_w"].as_int(), node["collide_h"].as_int())), hit_rect_(node.has_key("hit") ? rect(node["hit"]) : rect(node["hit_x"].as_int(), node["hit_y"].as_int(), node["hit_w"].as_int(), node["hit_h"].as_int())), platform_rect_(node.has_key("platform") ? rect(node["platform"]) : rect(node["platform_x"].as_int(), node["platform_y"].as_int(), node["platform_w"].as_int(), 1)), img_rect_(node.has_key("rect") ? rect(node["rect"]) : rect(node["x"].as_int(), node["y"].as_int(), node["w"].as_int(), node["h"].as_int())), feet_x_(node["feet_x"].as_int()), feet_y_(node["feet_y"].as_int()), accel_x_(node["accel_x"].as_int(INT_MIN)), accel_y_(node["accel_y"].as_int(INT_MIN)), velocity_x_(node["velocity_x"].as_int(INT_MIN)), velocity_y_(node["velocity_y"].as_int(INT_MIN)), nframes_(node["frames"].as_int(1)), nframes_per_row_(node["frames_per_row"].as_int(-1)), frame_time_(node["duration"].as_int(-1)), reverse_frame_(node["reverse"].as_bool()), play_backwards_(node["play_backwards"].as_bool()), scale_(node["scale"].as_int(2)), pad_(node["pad"].as_int()), rotate_(node["rotate"].as_int()), blur_(node["blur"].as_int()), rotate_on_slope_(node["rotate_on_slope"].as_bool()), damage_(node["damage"].as_int()), sounds_(util::split(node["sound"].as_string_default())), no_remove_alpha_borders_(node["no_remove_alpha_borders"].as_bool(false)), collision_areas_inside_frame_(true), current_palette_(-1) { std::vector<std::string> hit_frames = util::split(node["hit_frames"].as_string_default()); foreach(const std::string& f, hit_frames) { hit_frames_.push_back(boost::lexical_cast<int>(f)); }
void xml_writer_impl::write_instruction(const variant& instruction) { if (instruction.is<variant::Mapping>() && instruction.has_key(xml_target) && instruction.has_key(xml_data)) { m_os << "<?" << instruction[xml_target].as<std::string>() << " " << instruction[xml_data].as<std::string>() << "?>"; } else { boost::throw_exception(variant_error((boost::format("Expecting dictionary containing '%s' and '%s' for processing instruction") % xml_target % xml_data).str())); } }
grid::grid(const variant& v, game_logic::formula_callable* e) : widget(v, e), scrollable_widget(v, e), row_height_(0), selected_row_(-1), allow_selection_(false), must_select_(false), swallow_clicks_(false), hpad_(0), show_background_(false), max_height_(-1), allow_highlight_(true), set_h_(0), set_w_(0) { ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); if(v.has_key("on_select")) { ffl_on_select_ = get_environment()->create_formula(v["on_select"]); on_select_ = boost::bind(&grid::select_delegate, this, _1); } if(v.has_key("on_mouseover")) { ffl_on_mouseover_ = get_environment()->create_formula(v["on_mouseover"]); on_select_ = boost::bind(&grid::mouseover_delegate, this, _1); } ncols_ = v["columns"].as_int(1); if(v.has_key("column_widths")) { if(v["column_widths"].is_list()) { std::vector<int> li = v["column_widths"].as_list_int(); col_widths_.assign(li.begin(), li.end()); } else if(v["column_widths"].is_int()) { col_widths_.assign(ncols_, v["column_widths"].as_int()); } else { ASSERT_LOG(false, "grid: column_widths must be an int or list of ints"); } } else { col_widths_.assign(ncols_, 0); } if(v.has_key("column_alignments")) { if(v["column_alignments"].is_list()) { // XXX this could be a list of strings as well. int col = 0; foreach(const variant& c, v["column_alignments"].as_list()) { if(c.is_int()) { set_align(col, static_cast<COLUMN_ALIGN>(c.as_int())); } else if(c.is_string()) { const std::string& s = c.as_string(); if(s == "center" || s == "centre") { set_align(col, ALIGN_CENTER); } else if(s == "right") { set_align(col, ALIGN_RIGHT); } else if(s == "left") { set_align(col, ALIGN_LEFT); } else { ASSERT_LOG(false, "grid: column_alignments must be \"left\", \"right\" or \"center\""); } } else { ASSERT_LOG(false, "grid: column alignment members must be an integer or a string."); } col++; } } else if(v["column_alignments"].is_int()) {
scrollable_widget::scrollable_widget(const variant& v, game_logic::formula_callable* e) : widget(v,e), yscroll_(0), virtual_height_(0), step_(0), arrow_step_(0) { if(v.has_key("yscroll")) { yscroll_ = v["yscroll"].as_int(); } if(v.has_key("virtual_height")) { virtual_height_ = v["virtual_height"].as_int(); } if(v.has_key("step")) { arrow_step_ = step_ = v["step"].as_int(); } }
explicit SDLWindow(int width, int height, const variant& hints) : Window(width, height, hints), renderer_hint_(), renderer_(nullptr), context_(nullptr), nonfs_width_(width), nonfs_height_(height), request_major_version_(2), request_minor_version_(1), profile_(ProfileValue::COMPAT) { if(hints.has_key("renderer")) { if(hints["renderer"].is_string()) { renderer_hint_.emplace_back(hints["renderer"].as_string()); } else { renderer_hint_ = hints["renderer"].as_list_string(); } } else { renderer_hint_.emplace_back("opengl"); } // XXX figure out a better way to pass this hint. SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderer_hint_.front().c_str()); auto dpi_aware = hints["dpi_aware"].as_bool(false); if(dpi_aware) { SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); } else { SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "1"); } if(hints.has_key("version")) { const int version = hints["version"].as_int32(); request_major_version_ = version / 100; request_minor_version_ = version % 100; } if(hints.has_key("profile")) { const std::string profile = hints["profile"].as_string(); if(profile == "compatibility" || profile == "compat") { profile_ = ProfileValue::COMPAT; } else if(profile == "core") { profile_ = ProfileValue::CORE; } else if(profile == "es" || profile == "ES") { profile_ = ProfileValue::ES; } else { LOG_ERROR("Unrecognized profile setting '" << profile << "' defaulting to compatibility."); } } }
selector_widget::selector_widget(const variant& v, game_logic::formula_callable* e) : widget(v, e), current_selection_(v["selection"].as_int(0)) { if(v.has_key("list") || v.has_key("children")) { const variant& l = v.has_key("list") ? v["list"] : v["children"]; ASSERT_LOG(l.is_list(), "'list'/'children' attribute must be a list"); foreach(const variant& child, l.as_list()) { if(child.is_list()) { ASSERT_LOG(child.num_elements() == 2, "items in the sub-list must have two elements."); widget_ptr w; if(child[1].is_map()) { w = widget_factory::create(child[1], e); } else { w = child[1].try_convert<widget>(); ASSERT_LOG(w != NULL, "Couldn't convert second element to widget."); } list_.push_back(selector_pair(child[0].as_string(), w)); } else if(child.is_string()) { const std::string& s = child.as_string(); list_.push_back(selector_pair(s, widget_ptr(new label(s)))); } else { widget_ptr w; std::string s; if(child.is_map()) { w = widget_factory::create(child, e); ASSERT_LOG(child.has_key("id") || child.has_key("select_string"), "list items must supply 'id' or 'select_string' attribute."); s = child.has_key("id") ? child["id"].as_string() : child["select_string"].as_string(); } else { w = child.try_convert<widget>(); ASSERT_LOG(w != NULL, "Couldn't convert item to widget."); ASSERT_LOG(!w->id().empty(), "list items must have 'id' attribute"); s = w->id(); } list_.push_back(selector_pair(s, w)); } } } if(v.has_key("on_change")) { change_handler_ = get_environment()->create_formula(v["on_change"]); on_change_ = boost::bind(&selector_widget::change_delegate, this, _1); } if(v.has_key("on_select")) { select_handler_ = get_environment()->create_formula(v["on_select"]); on_select_ = boost::bind(&selector_widget::select_delegate, this, _1); } init(); }
Animation read_animation(const variant& v) { Animation result; if(v.has_key("duration")) { result.duration = v["duration"].as_decimal().as_float(); } else { result.duration = -1.0; } for(variant t : v["transforms"].as_list()) { AnimationTransform transform; transform.children_only = t["children_only"].as_bool(false); transform.layer = t["layer"].as_string(); if(t.has_key("pivots")) { std::vector<std::string> pivots = t["pivots"].as_list_string(); ASSERT_LOG(pivots.size() == 2, "Must have two pivots in animation: " << t.to_debug_string()); transform.pivot_src = pivots[0]; transform.pivot_dst = pivots[1]; transform.rotation_formula = game_logic::formula::create_optional_formula(t["rotation"]); } transform.translation_formula = game_logic::formula::create_optional_formula(t["translation"]); result.transforms.push_back(transform); } return result; }
std::vector<CastlePart> parse_dir(const variant& node) { std::vector<CastlePart> res; const std::vector<std::string> keys = { "bl", "br", "l", "r", "tl", "tr" }; ASSERT_LOG(node.is_map(), "must be a map type."); for(auto key : keys) { ASSERT_LOG(node.has_key(key), "Must have attribute '" << key << "' in definition."); const variant& dir = node[key]; ASSERT_LOG(dir.has_key("rect"), "Attribute '" << key << "' must have 'rect' definition."); CastlePart cp; cp.r_ = rect(dir["rect"]); if(dir.has_key("border")) { ASSERT_LOG(dir["border"].num_elements() == 4, "'border' attribute must be list of 4 integers."); for(int n = 0; n != 4; ++n) { cp.border_[n] = dir["border"][n].as_int32(); } } else { for(int n = 0; n != 4; ++n) { cp.border_[n] = 0; } } if(dir.has_key("offset")) { cp.offs_ = point(dir["offset"]); } else { cp.offs_.x = cp.offs_.y = 0; } res.emplace_back(cp); } return res; }
explicit CastleDef(const std::string& name, const variant& node) : name_(name) { using namespace KRE; ASSERT_LOG(node.has_key("image"), "No 'image' attribute in castle definition."); const std::string tex_name = node["image"].as_string(); texture_ = Texture::createTexture(tex_name, TextureType::TEXTURE_2D, 4); //texture_->setFiltering(Texture::Filtering::LINEAR, Texture::Filtering::LINEAR, Texture::Filtering::POINT); texture_->setAddressModes(-1, Texture::AddressMode::BORDER, Texture::AddressMode::BORDER); ASSERT_LOG(node.has_key("concave") && node.has_key("convex"), "Castle definition must have 'concave' and 'convex' attributes."); concave_ = parse_dir(node["concave"]); convex_ = parse_dir(node["convex"]); }
bar_widget::bar_widget(const variant& v, game_logic::formula_callable* e) : widget(v, e), segments_(v["segments"].as_int(1)), segment_length_(v["segment_length"].as_int(5)), rotate_(GLfloat(v["rotation"].as_decimal().as_float())), tick_width_(v["tick_width"].as_int(1)), scale_(2.0f), drained_segments_(v["drained"].as_int(0)), animating_(false), drain_rate_(v["drain_rate"].as_decimal(decimal(10.0)).as_float()), total_bar_length_(0), drained_bar_length_(0), active_bar_length_(0), left_cap_width_(0), right_cap_width_(0), animation_end_point_unscaled_(0.0f), animation_current_position_(0.0f), drained_segments_after_anim_(0), bar_max_width_(v["max_width"].as_int()) { if(v.has_key("bar_color")) { bar_color_ = graphics::color(v["bar_color"]).as_sdl_color(); } else { bar_color_ = graphics::color("red").as_sdl_color(); } if(v.has_key("tick_color")) { tick_mark_color_ = graphics::color(v["tick_color"]).as_sdl_color(); } else { tick_mark_color_ = graphics::color("black").as_sdl_color(); } if(v.has_key("drained_bar_color")) { drained_bar_color_ = graphics::color(v["drained_bar_color"]).as_sdl_color(); } else { drained_bar_color_ = graphics::color("black").as_sdl_color(); } if(v.has_key("drained_tick_color")) { drained_tick_mark_color_ = graphics::color(v["drained_tick_color"]).as_sdl_color(); } else { drained_tick_mark_color_ = graphics::color("white").as_sdl_color(); } if(v.has_key("scale")) { scale_ = GLfloat(v["scale"].as_decimal().as_float()); } ASSERT_LOG(v.has_key("bar"), "Missing 'bar' attribute"); init_bar_section(v["bar"], &bar_); ASSERT_LOG(v.has_key("left_cap"), "Missing 'left_cap' attribute"); init_bar_section(v["left_cap"], &left_cap_); ASSERT_LOG(v.has_key("right_cap"), "Missing 'right_cap' attribute"); init_bar_section(v["right_cap"], &right_cap_); ASSERT_GT(segments_, 0); ASSERT_GT(segment_length_, 0); if(drained_segments_ > segments_) { drained_segments_ = segments_; } if(drained_segments_ < 0) { drained_segments_ = 0; } bar_height_ = height(); init(); }
RenderTarget::RenderTarget(const variant& node) : width_(0), height_(0), color_attachments_(1), depth_attachment_(false), stencil_attachment_(false), multi_sampling_(false), multi_samples_(0), clear_color_(0.0f, 0.0f, 0.0f, 1.0f) { ASSERT_LOG(node.is_map(), "RenderTarget definitions must be maps: " << node.to_debug_string()); ASSERT_LOG(node.has_key("width"), "Render target must have a 'width' attribute."); ASSERT_LOG(node.has_key("height"), "Render target must have a 'height' attribute."); width_ = node["width"].as_int32(); height_ = node["height"].as_int32(); if(node.has_key("color_planes")) { color_attachments_ = node["color_planes"].as_int32(); ASSERT_LOG(color_attachments_ >= 0, "Number of 'color_planes' must be zero or greater: " << color_attachments_); } if(node.has_key("depth_buffer")) { depth_attachment_ = node["depth_buffer"].as_bool(); } if(node.has_key("stencil_buffer")) { stencil_attachment_ = node["stencil_buffer"].as_bool(); } if(node.has_key("use_multisampling")) { multi_sampling_ = node["use_multisampling"].as_bool(); if(node.has_key("samples")) { multi_samples_ = node["samples"].as_int32(); } } // XXX Maybe we need to add some extra filtering from min to max values based on order ? }
graphical_font_label::graphical_font_label(const variant& v, game_logic::formula_callable* e) : widget(v,e) { text_ = v["text"].as_string_default("TEXT"); font_ = graphical_font::get(v.has_key("font") ? v["font"].as_string() : "door_label"); ASSERT_LOG(font_.get(), "UNKNOWN FONT: " << v["font"].as_string()); size_ = v["size"].as_int(12); reset_text_dimensions(); }
void bar_widget::init_bar_section(const variant&v, bar_section* b) { b->texture = graphics::texture::get(v["image"].as_string()); if(v.has_key("area")) { ASSERT_LOG(v["area"].is_list() && v["area"].num_elements() == 4, "'area' attribute must be four element list."); b->area = rect(v["area"][0].as_int(), v["area"][1].as_int(), v["area"][2].as_int(), v["area"][3].as_int()); } else { b->area = rect(0, 0, b->texture.width(), b->texture.height()); } }
EffectPtr DisplayDeviceOpenGL::createEffect(const variant& node) { ASSERT_LOG(node.has_key("type") && node["type"].is_string(), "Effects must have 'type' attribute as string: " << node.to_debug_string()); const std::string& type = node["type"].as_string(); if(type == "stipple") { return std::make_shared<OpenGL::StippleEffect>(node); } // XXX Add more effects here as and if needed. return EffectPtr(); }
explicit emit_object(particle_system_container* parent, const variant& node) : parent_container_(parent) { ASSERT_LOG(parent != NULL, "FATAL: PSYSTEM2: parent is null"); if(node.has_key("name")) { name_ = node["name"].as_string(); } else { std::stringstream ss; ss << "emit_object_" << int(get_random_float()); name_ = ss.str(); } }
bool wml_serializable_formula_callable::deserialize_obj(const variant& var, variant* target) { for(const std::pair<std::string, std::function<variant(variant)> >& p : type_registry()) { if(var.has_key(p.first)) { *target = p.second(var); return true; } } return false; }
button::button(const variant& v, game_logic::formula_callable* e) : widget(v,e), down_(false) { variant label_var = v["label"]; label_ = label_var.is_map() ? widget_factory::create(label_var, e) : new label(label_var.as_string_default("Button"), graphics::color_white()); ASSERT_LOG(v.has_key("on_click"), "Button must be supplied with an on_click handler"); // create delegate for onclick ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); click_handler_ = get_environment()->create_formula(v["on_click"]); onclick_ = boost::bind(&button::click, this); button_resolution_ = v["resolution"].as_string_default("normal") == "normal" ? BUTTON_SIZE_NORMAL_RESOLUTION : BUTTON_SIZE_DOUBLE_RESOLUTION; button_style_ = v["style"].as_string_default("default") == "default" ? BUTTON_STYLE_DEFAULT : BUTTON_STYLE_NORMAL; hpadding_ = v["hpad"].as_int(10); vpadding_ = v["vpad"].as_int(4); if(v.has_key("padding")) { ASSERT_LOG(v["padding"].num_elements() == 2, "Incorrect number of padding elements specifed." << v["padding"].num_elements()); hpadding_ = v["padding"][0].as_int(); vpadding_ = v["padding"][1].as_int(); } setup(); }
void fixed_program::set_fixed_attributes(const variant& node) { program::set_fixed_attributes(node); std::cerr << "shader program: " << name() << "(" << get() << ")"; if(node.has_key("vertex")) { vtx_coord_ = get_attribute(node["vertex"].as_string()); std::cerr << ", vtx_coord: " << vtx_coord_; } if(node.has_key("color")) { col_coord_ = get_attribute(node["color"].as_string()); std::cerr << ", col_coord: " << col_coord_; } if(node.has_key("colour")) { col_coord_ = get_attribute(node["colour"].as_string()); std::cerr << ", col_coord: " << col_coord_; } if(node.has_key("texcoord")) { tex_coord_[0] = get_attribute(node["texcoord"].as_string()); std::cerr << ", tex_coord0: " << tex_coord_[0]; } if(node.has_key("texcoord0")) { tex_coord_[0] = get_attribute(node["texcoord0"].as_string()); std::cerr << ", tex_coord0: " << tex_coord_[0]; } if(node.has_key("texcoord1")) { tex_coord_[1] = get_attribute(node["texcoord1"].as_string()); std::cerr << ", tex_coord1: " << tex_coord_[1]; } std::cerr << std::endl; }
slider::slider(const variant& v, game_logic::formula_callable* e) : widget(v,e), dragging_(false) { ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); onchange_ = boost::bind(&slider::change_delegate, this, _1); ffl_handler_ = get_environment()->create_formula(v["on_change"]); if(v.has_key("on_drag_end")) { ondragend_ = boost::bind(&slider::dragend_delegate, this, _1); ffl_end_handler_ = get_environment()->create_formula(v["on_drag_end"]); } position_ = v.has_key("position") ? v["position"].as_decimal().as_float() : 0.0; slider_left_ = v.has_key("slider_left") ? widget_factory::create(v["slider_left"], e) : new gui_section_widget("slider_side_left", -1, -1, 2); slider_right_ = v.has_key("slider_right") ? widget_factory::create(v["slider_right"], e) : new gui_section_widget("slider_side_right", -1, -1, 2); slider_middle_ = v.has_key("slider_middle") ? widget_factory::create(v["slider_middle"], e) : new gui_section_widget("slider_middle", -1, -1, 2); slider_button_ = v.has_key("slider_button") ? widget_factory::create(v["slider_button"], e) : new gui_section_widget("slider_button", -1, -1, 2); init(); set_dim(width_+slider_left_->width()*2, slider_button_->height()); }
key_button::key_button(const variant& v, game_logic::formula_callable* e) : widget(v,e), normal_button_image_set_(framed_gui_element::get("regular_button")), depressed_button_image_set_(framed_gui_element::get("regular_button_pressed")), focus_button_image_set_(framed_gui_element::get("regular_button_focus")), current_button_image_set_(normal_button_image_set_), grab_keys_(false) { std::string key = v["key"].as_string(); key_ = get_key_sym(key); label_ = v.has_key("label") ? widget_factory::create(v["label"], e) : widget_ptr(new graphical_font_label(key, "door_label", 2)); button_resolution_ = v["resolution"].as_string_default("normal") == "normal" ? BUTTON_SIZE_NORMAL_RESOLUTION : BUTTON_SIZE_DOUBLE_RESOLUTION; set_dim(label_->width()+hpadding*2,label_->height()+vpadding*2); }
voxel_object::voxel_object(const variant& node) // The initializer list should NOT read from 'node'. It should only // set up default values. Read from node in the body. : translation_(0.0f), rotation_(0.0f), scale_(1.0f), cycle_(0), paused_(false), is_mouseover_(false) { if(node.has_key("type")) { const std::string type = node["type"].as_string(); const voxel_object* prototype = voxel_object_type::get(type)->prototype(); if(prototype) { *this = *prototype; } type_ = type; } if(!shader_ || node.has_key("shader")) { shader_ = gles2::shader_program::get_global(node["shader"].as_string())->shader(); } if(!model_ || node.has_key("model")) { std::map<variant,variant> m; m[variant("model")] = variant(model_path_get_or_die(node["model"].as_string())); model_.reset(new voxel_model(variant(&m))); model_->set_animation("stand"); } if(node.has_key("translation")) { translation_ = variant_to_vec3(node["translation"]); } if(node.has_key("rotation")) { rotation_ = variant_to_vec3(node["rotation"]); } if(node.has_key("scale")) { if(node["scale"].is_decimal()) { float scale = float(node["scale"].as_decimal().as_float()); scale_ = glm::vec3(scale, scale, scale); } else { scale_ = variant_to_vec3(node["scale"]); } } if(node.has_key("widgets")) { if(node["widgets"].is_list()) { for(int n = 0; n != node["widgets"].num_elements(); ++n) { widgets_.insert(widget_factory::create(node["widgets"][n], this)); } } } a_normal_ = shader_->get_fixed_attribute("normal"); mvp_matrix_ = shader_->get_fixed_uniform("mvp_matrix"); }
void custom_object_widget::init(const variant& v) { entity_.reset(); handle_process_on_entity_ = v["handle_process"].as_bool(false); if(v["object"].is_string()) { // type name, has obj_x, obj_y, facing entity_ = entity_ptr(new custom_object(v["object"].as_string(), v["obj_x"].as_int(0), v["obj_y"].as_int(0), v["facing"].as_int(1))); entity_->finish_loading(NULL); } else if(v["object"].is_map()) { entity_ = entity_ptr(new custom_object(v["object"])); entity_->finish_loading(NULL); } else { entity_ = v["object"].try_convert<entity>(); ASSERT_LOG(entity_ != NULL, "Couldn't convert 'object' attribue to an entity"); entity_->finish_loading(NULL); entity_->validate_properties(); } if(v.has_key("properties")) { ASSERT_LOG(v["properties"].is_map(), "properties field must be a map"); const variant& properties = v["properties"]; variant keys = properties.get_keys(); for(int n = 0; n != keys.num_elements(); ++n) { variant value = properties[keys[n]]; entity_->mutate_value(keys[n].as_string(), value); } } if(v.has_key("commands")) { do_commands_on_process = 10; commands_handler_ = entity_->create_formula(v["commands"]); using namespace game_logic; map_formula_callable_ptr callable = map_formula_callable_ptr(new map_formula_callable(entity_.get())); callable->add("id", variant(id())); variant value = commands_handler_->execute(*callable); entity_->execute_command(value); } if(v.has_key("on_click")) { click_handler_ = get_environment()->create_formula(v["on_click"]); on_click_ = boost::bind(&custom_object_widget::click, this, _1); } if(v.has_key("on_mouse_enter")) { mouse_enter_handler_ = get_environment()->create_formula(v["on_mouse_enter"]); on_mouse_enter_ = boost::bind(&custom_object_widget::mouse_enter, this); } if(v.has_key("on_mouse_leave")) { mouse_leave_handler_ = get_environment()->create_formula(v["on_mouse_leave"]); on_mouse_leave_ = boost::bind(&custom_object_widget::mouse_leave, this); } if(v.has_key("overlay") && v["overlay"].is_null() == false) { overlay_ = widget_factory::create(v["overlay"], get_environment()); } set_dim(entity_->current_frame().width(), entity_->current_frame().height()); }
Window::Window(int width, int height, const variant& hints) : width_(hints["width"].as_int32(width)), height_(hints["height"].as_int32(height)), logical_width_(hints["logical_width"].as_int32(width_)), logical_height_(hints["logical_height"].as_int32(height_)), use_16bpp_(hints["use_16bpp"].as_bool(false)), use_multi_sampling_(hints["use_multisampling"].as_bool(false)), samples_(hints["samples"].as_int32(4)), is_resizeable_(hints["resizeable"].as_bool(false)), is_borderless_(hints["borderless"].as_bool(false)), fullscreen_mode_(hints["fullscreen"].as_bool(false) ? FullScreenMode::FULLSCREEN_WINDOWED : FullScreenMode::WINDOWED), title_(hints["title"].as_string_default("")), use_vsync_(hints["use_vsync"].as_bool(false)), clear_color_(0.0f,0.0f,0.0f,1.0f), view_port_(0, 0, width_, height_), display_(nullptr) { if(hints.has_key("clear_color")) { clear_color_ = Color(hints["clear_color"]); } }
void Material::init(const variant& node) { blend_.set(BlendModeConstants::BM_SRC_ALPHA, BlendModeConstants::BM_ONE_MINUS_SRC_ALPHA); if(node.is_string()) { name_ = node.as_string(); tex_.emplace_back(DisplayDevice::createTexture(name_)); } else if(node.is_map()) { name_ = node["name"].as_string(); // XXX: technically a material could have multiple technique's and passes -- ignoring for now. ASSERT_LOG(node.has_key("technique"), "PSYSTEM2: 'material' must have 'technique' attribute."); ASSERT_LOG(node["technique"].has_key("pass"), "PSYSTEM2: 'material' must have 'pass' attribute."); const variant& pass = node["technique"]["pass"]; use_lighting_ = pass["lighting"].as_bool(false); use_fog_ = pass["fog_override"].as_bool(false); do_depth_write_ = pass["depth_write"].as_bool(true); do_depth_check_ = pass["depth_check"].as_bool(true); if(pass.has_key("scene_blend")) { blend_.set(pass["scene_blend"]); } if(pass.has_key("texture_unit")) { if(pass["texture_unit"].is_map()) { tex_.emplace_back(createTexture(pass["texture_unit"])); } else if(pass["texture_unit"].is_list()) { for(size_t n = 0; n != pass["texture_unit"].num_elements(); ++n) { tex_.emplace_back(createTexture(pass["texture_unit"][n])); } } else { ASSERT_LOG(false, "'texture_unit' attribute must be map or list "); } } if(pass.has_key("rect")) { draw_rect_ = rectf(pass["rect"]); } } else { ASSERT_LOG(false, "Materials(Textures) must be either a single string filename or a map."); } }
scrollbar_widget::scrollbar_widget(const variant& v, game_logic::formula_callable* e) : widget(v,e), window_pos_(0), window_size_(0), range_(0), step_(0), dragging_handle_(false), drag_start_(0), drag_anchor_y_(0) { handler_ = boost::bind(&scrollbar_widget::handler_delegate, this, _1); ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); ffl_handler_ = get_environment()->create_formula(v["on_scroll"]); up_arrow_ = v.has_key("up_arrow") ? widget_factory::create(v["up_arrow"], e) : new gui_section_widget(UpArrow); down_arrow_ = v.has_key("down_arrow") ? widget_factory::create(v["down_arrow"], e) : new gui_section_widget(DownArrow); handle_ = v.has_key("handle") ? widget_factory::create(v["handle"], e) : new gui_section_widget(VerticalHandle); handle_bot_ = v.has_key("handle_bottom") ? widget_factory::create(v["handle_bottom"], e) : new gui_section_widget(VerticalHandleBot); handle_top_ = v.has_key("handle_top") ? widget_factory::create(v["handle_top"], e) : new gui_section_widget(VerticalHandleTop); background_ = v.has_key("background") ? widget_factory::create(v["background"], e) : new gui_section_widget(VerticalBackground); if(v.has_key("range")) { std::vector<int> range = v["range"].as_list_int(); ASSERT_EQ(range.size(), 2); set_range(range[0], range[1]); } }
grid::grid(const variant& v, game_logic::formula_callable* e) : scrollable_widget(v, e), row_height_(v["row_height"].as_int(0)), selected_row_(-1), allow_selection_(false), must_select_(false), swallow_clicks_(false), hpad_(0), show_background_(false), max_height_(-1), allow_highlight_(true), set_h_(0), set_w_(0), default_selection_(v["default_select"].as_int(-1)), draw_selection_highlight_(v["draw_selection_highlighted"].as_bool(false)) { ASSERT_LOG(get_environment() != 0, "You must specify a callable environment"); if(v.has_key("on_select")) { const variant on_select_value = v["on_select"]; if(on_select_value.is_function()) { ASSERT_LOG(on_select_value.min_function_arguments() <= 1 && on_select_value.max_function_arguments() >= 1, "on_select grid function should take 1 argument: " << v.debug_location()); static const variant fml("fn(selection)"); ffl_on_select_.reset(new game_logic::formula(fml)); game_logic::map_formula_callable* callable = new game_logic::map_formula_callable; callable->add("fn", on_select_value); select_arg_.reset(callable); } else { ffl_on_select_ = get_environment()->create_formula(on_select_value); } on_select_ = boost::bind(&grid::select_delegate, this, _1); } if(v.has_key("on_mouseover")) { allow_selection_ = true; on_mouseover_ = boost::bind(&grid::mouseover_delegate, this, _1); const variant on_mouseover_value = v["on_mouseover"]; if(on_mouseover_value.is_function()) { ASSERT_LOG(on_mouseover_value.min_function_arguments() <= 1 && on_mouseover_value.max_function_arguments() >= 1, "on_mouseover grid function should take 1 argument: " << v.debug_location()); static const variant fml("fn(selection)"); ffl_on_mouseover_.reset(new game_logic::formula(fml)); game_logic::map_formula_callable* callable = new game_logic::map_formula_callable; callable->add("fn", on_mouseover_value); mouseover_arg_.reset(callable); } else { ffl_on_mouseover_ = get_environment()->create_formula(v["on_mouseover"]); } } ncols_ = v["columns"].as_int(1); if(v.has_key("column_widths")) { if(v["column_widths"].is_list()) { ASSERT_LOG(v["column_widths"].num_elements() == ncols_, "List of column widths must have " << ncols_ << " elements"); std::vector<int> li = v["column_widths"].as_list_int(); col_widths_.assign(li.begin(), li.end()); } else if(v["column_widths"].is_int()) { col_widths_.assign(ncols_, v["column_widths"].as_int()); } else { ASSERT_LOG(false, "grid: column_widths must be an int or list of ints"); } } else { col_widths_.assign(ncols_, 0); } col_aligns_.resize(ncols_); if(v.has_key("column_alignments")) { if(v["column_alignments"].is_list()) { // XXX this could be a list of strings as well. int col = 0; foreach(const variant& c, v["column_alignments"].as_list()) { if(c.is_int()) { set_align(col, static_cast<COLUMN_ALIGN>(c.as_int())); } else if(c.is_string()) { const std::string& s = c.as_string(); if(s == "center" || s == "centre") { set_align(col, ALIGN_CENTER); } else if(s == "right") { set_align(col, ALIGN_RIGHT); } else if(s == "left") { set_align(col, ALIGN_LEFT); } else { ASSERT_LOG(false, "grid: column_alignments must be \"left\", \"right\" or \"center\""); } } else { ASSERT_LOG(false, "grid: column alignment members must be an integer or a string."); } col++; } } else if(v["column_alignments"].is_int()) {