std::shared_ptr<GroupLevelObj> GroupLevelObj::from_prefab(const std::string& name) { try { PrefabFile prefab = PrefabFile::from_resource(name); std::shared_ptr<GroupLevelObj> group = std::make_shared<GroupLevelObj>(); group->m_name = name; for(auto it = prefab.get_objects().begin(); it != prefab.get_objects().end(); ++it) { LevelObjPtr obj = LevelObjFactory::create(*it); if (obj) { group->add_child(obj); } } group->set_overrides(prefab.get_overrides()); return group; } catch(const std::exception& err) { log_error(err.what()); return std::shared_ptr<GroupLevelObj>(); } }
std::unique_ptr<EditorLevel> EditorLevel::from_prefab_file(const Pathname& pathname) { log_info("%1%", pathname.str()); // Load the level from the file - we don't care what it's res_name is. PrefabFile prefab = PrefabFile::from_path(pathname); std::unique_ptr<EditorLevel> level(new EditorLevel); // FIMXE: there would be better way to handle prefab size, but it's // probably not worth the effort level->impl->size.width = 1920; level->impl->size.height = 1200; // FIXME: overrides are getting ignored // Get the objects auto objs = prefab.get_objects(); for (auto i = objs.begin(); i != objs.end(); i++) { LevelObjPtr obj = LevelObjFactory::create(*i); if (obj) { // move origin of the level to the center of it obj->set_pos(obj->get_pos() + Vector3f(static_cast<float>(level->impl->size.width)/2.0f, static_cast<float>(level->impl->size.height)/2.0f)); level->add_object(obj); } } level->sort(); return level; }
int main(int argc, char** argv) { std::vector<Pathname> files; bool crop = false; CommandLine argp; argp.add_usage("[OPTIONS]... LEVELFILE OUTPUTFILE"); argp.add_option('h', "help", "", "Displays this help"); argp.add_option('b', "background", "RRGGBBAA", "Set background color"); argp.add_option('c', "crop", "", "crop output to the actual objects rendered, not levelsize "); argp.parse_args(argc, argv); while (argp.next()) { switch (argp.get_key()) { case 'h': argp.print_help(); exit(EXIT_SUCCESS); break; case 'c': crop = true; break; case 'b': // FIXME: not implemented break; case CommandLine::REST_ARG: files.push_back(Pathname(argp.get_argument(), Pathname::SYSTEM_PATH)); break; } } if (files.size() != 2) { argp.print_help(); exit(EXIT_SUCCESS); } else { g_path_manager.set_path("data/"); Resource::init(); // render all the objects WorldObjRenderer renderer; Size size; if (System::get_file_extension(files[0].get_raw_path()) == "prefab") { PrefabFile prefab = PrefabFile::from_path(files[0]); renderer.process(prefab.get_objects()); crop = true; } else { PingusLevel plf(files[0]); renderer.process(plf.get_objects()); size = plf.get_size(); } Surface out_surface; if (crop) { Rect rect = renderer.get_clip_rect(); out_surface = Surface(rect.get_width(), rect.get_height()); // FIXME: alpha doesn't work, as the PNG saver can't handle that out_surface.fill(Color(255, 255, 255, 255)); renderer.blit(out_surface, -rect.left, -rect.top); // create a .sprite file to handle the offset std::string outfile = System::cut_file_extension(files[1].get_sys_path()) + ".sprite"; Vector2i offset(rect.left, rect.top); std::ostringstream out; SExprFileWriter writer(out); writer.begin_section("pingus-sprite"); writer.write_string("image", System::cut_file_extension(System::basename(files[0].get_raw_path())) + ".png"); writer.write_vector2i("offset", offset); writer.end_section(); out << std::endl; log_info("writing: %1%", outfile); System::write_file(outfile, out.str()); } else { out_surface = Surface(size.width, size.height); // FIXME: alpha doesn't work, as the PNG saver can't handle that out_surface.fill(Color(255, 255, 255, 255)); renderer.blit(out_surface); } Screenshot::save(out_surface.get_surface(), files[1].get_sys_path()); Resource::deinit(); } return 0; }
void WorldObjRenderer::process(const FileReader& reader) { // FIXME: does not handle sprite alignment // FIXME: does not handle remove groundpieces // FIXME: does not handle liquid if (reader.get_name() == "surface-background" || reader.get_name() == "starfield-background" || reader.get_name() == "solidcolor-background" || reader.get_name() == "snow-generator" || reader.get_name() == "rain-generator") { // ignore } else if (reader.get_name() == "groundpiece" || reader.get_name() == "liquid" || reader.get_name() == "exit" || reader.get_name() == "hotspot") { process_object_with_surface(reader); } else if (reader.get_name() == "entrance") { Vector3f pos; reader.read_vector("position", pos); render_sprite(ResDescriptor("entrances/generic"), pos); } else if (reader.get_name() == "spike") { Vector3f pos; reader.read_vector("position", pos); render_surface(ResDescriptor("traps/spike_editor"), pos); } else if (reader.get_name() == "switchdoor-switch") { Vector3f pos; reader.read_vector("position", pos); render_surface(ResDescriptor("worldobjs/switchdoor_switch"), pos); } else if (reader.get_name() == "switchdoor-door") { Vector3f pos; reader.read_vector("position", pos); render_surface(ResDescriptor("worldobjs/switchdoor_box"), pos); } else if (reader.get_name() == "group") { FileReader objects = reader.read_section("objects"); process(objects.get_sections()); } else if (reader.get_name() == "prefab") { std::string name; if (!reader.read_string("name", name)) { log_error("'name' tag missing for prefab"); } else { PrefabFile prefab = PrefabFile::from_resource(name); Vector3f position; reader.read_vector("position", position); push_translate(static_cast<int>(position.x), static_cast<int>(position.y)); process(prefab.get_objects()); pop_translate(); } } else { log_error("unknown object type: %1%", reader.get_name()); } }