예제 #1
0
   Font::Font(const string& font)
   {
      string dir = Utils::basedir(font);

      xml_document doc;
      if (!doc.load_file(font.c_str()))
         throw runtime_error(Utils::join("Failed to load font: ", font, "."));

      xml_node glyph       = doc.child("font").child("glyphs");
      char start_ascii = glyph.attribute("startascii").as_int();

      int width   = glyph.attribute("width").as_int();
      int height  = glyph.attribute("height").as_int();
      glyphwidth  = glyph.attribute("glyphwidth").as_int();
      glyphheight = glyph.attribute("glyphheight").as_int();
      const char_t* source = glyph.attribute("source").value();

      if (!width || !height || !glyphwidth || !glyphheight)
         throw logic_error("Invalid glpyh arguments.");

      SurfaceCache cache;
      Surface surf = cache.from_image(Utils::join(dir, "/", source));

      if (surf.rect().w != width * glyphwidth || surf.rect().h != height * glyphheight)
         throw logic_error("Geometry of font and attributes do not match.");

      for (int y = 0; y < height; y++)
      {
         for (int x = 0; x < width; x++, start_ascii++)
         {
            surf_map[start_ascii] = surf.sub(Rect(Pos(x * glyphwidth, y * glyphheight),
                  glyphwidth, glyphheight));

            surf_map[start_ascii].ignore_camera(true);
         }
      }
   }
예제 #2
0
   void Tilemap::add_tileset(std::map<unsigned, Surface>& tiles, xml_node node)
   {
      int first_gid  = node.attribute("firstgid").as_int();
      int id_cnt     = 0;
      int tilewidth  = node.attribute("tilewidth").as_int();
      int tileheight = node.attribute("tileheight").as_int();

      pugi::xml_node image     = node.child("image");
      const char *source    = image.attribute("source").value();
      int width      = image.attribute("width").as_int();
      int height     = image.attribute("height").as_int();

#if 0
      std::cerr << "Adding tileset:" <<
         " Name: " << node.attribute("name").value() <<
         " Gid: " << first_gid <<
         " Tilewidth: " << tilewidth <<
         " Tileheight: " << tileheight <<
         " Source: " << source <<
         " Width: " << width <<
         " Height: " << height << std::endl;
#endif

      if (!width || !height || !tilewidth || !tileheight)
         throw std::logic_error("Tilemap is malformed.");

      SurfaceCache cache;
      Blit::Surface surf = cache.from_image(Utils::join(dir, "/", source));

      if (surf.rect().w != width || surf.rect().h != height)
         throw std::logic_error("Tilemap geometry does not correspond with image values.");

      std::map<std::basic_string<char>, std::basic_string<char> > global_attr = get_attributes(node.child("properties"), "property");

#if 0
      std::cerr << "Dumping attrs:" << std::endl;
      for (auto& attr : global_attr)
         std::cerr << "Found global attr (" << attr.first << " => " << attr.second << ")." << std::endl;
      std::cerr << "Dumped attrs." << std::endl;
#endif

      for (int y = 0; y < height; y += tileheight)
      {
         for (int x = 0; x < width; x += tilewidth, id_cnt++)
         {
            int id = first_gid + id_cnt;
            tiles[id] = surf.sub({{x, y}, tilewidth, tileheight});
            std::copy(global_attr.begin(), global_attr.end(), std::inserter(tiles[id].attr(), tiles[id].attr().begin())); 
         }
      }

      // Load all attributes for a tile into the surface.
      for (auto tile = node.child("tile"); tile; tile = tile.next_sibling("tile"))
      {
         int id = first_gid + tile.attribute("id").as_int();

         std::map<std::basic_string<char>, std::basic_string<char> > attrs = get_attributes(tile.child("properties"), "property");
         std::copy(global_attr.begin(), global_attr.end(), std::inserter(attrs, attrs.begin()));

         auto itr = attrs.find("sprite");

         if (itr != attrs.end())
            tiles[id] = cache.from_sprite(Utils::join(dir, "/", itr->second));

         tiles[id].attr() = std::move(attrs);
      }
   }