/** * \brief Draws the foreground of the map. */ void Map::draw_foreground() { const int screen_width = visible_surface->get_width(); const int screen_height = visible_surface->get_height(); // If the map is too small for the screen, add black bars outside the map. // TODO make the same optimization as for the background (avoid fill_with_color) const int map_width = get_width(); if (map_width < screen_width) { int bar_width = (screen_width - map_width) / 2; Rectangle dst_position(0, 0, bar_width, screen_height); visible_surface->fill_with_color(Color::get_black(), dst_position); dst_position.set_x(bar_width + map_width); visible_surface->fill_with_color(Color::get_black(), dst_position); } const int map_height = get_height(); if (map_height < screen_height) { int bar_height = (screen_height - map_height) / 2; Rectangle dst_position(0, 0, screen_width, bar_height); visible_surface->fill_with_color(Color::get_black(), dst_position); dst_position.set_y(bar_height + map_height); visible_surface->fill_with_color(Color::get_black(), dst_position); } }
/** * \brief Draws the tile on the specified surface. * \param dst_surface the destination surface * \param viewport coordinates of the top-left corner of dst_surface * relative to the map */ void Tile::draw(Surface& dst_surface, const Rectangle& viewport) { Rectangle dst_position(get_top_left_x() - viewport.get_x(), get_top_left_y() - viewport.get_y(), get_width(), get_height()); tile_pattern->fill_surface(dst_surface, dst_position, get_map().get_tileset(), viewport); }
/** * \brief Builds a surface with black bars when the map is smaller than the * quest size. */ void Map::build_foreground_surface() { RefCountable::unref(foreground_surface); const int screen_width = visible_surface->get_width(); const int screen_height = visible_surface->get_height(); // If the map is too small for the screen, add black bars outside the map. const int map_width = get_width(); const int map_height = get_height(); if (map_width >= screen_width && map_height >= screen_height) { // Nothing to do. return; } foreground_surface = Surface::create(visible_surface->get_size()); RefCountable::ref(foreground_surface); // Keep this surface as software destination because it is built only once. if (map_width < screen_width) { int bar_width = (screen_width - map_width) / 2; Rectangle dst_position(0, 0, bar_width, screen_height); foreground_surface->fill_with_color(Color::get_black(), dst_position); dst_position.set_x(bar_width + map_width); foreground_surface->fill_with_color(Color::get_black(), dst_position); } if (map_height < screen_height) { int bar_height = (screen_height - map_height) / 2; Rectangle dst_position(0, 0, screen_width, bar_height); foreground_surface->fill_with_color(Color::get_black(), dst_position); dst_position.set_y(bar_height + map_height); foreground_surface->fill_with_color(Color::get_black(), dst_position); } }
/** * \brief Draws the tile on the map. */ void DynamicTile::draw_on_map() { if (!is_drawn()) { return; } const Rectangle& camera_position = get_map().get_camera_position(); Rectangle dst(0, 0); Rectangle dst_position(get_top_left_x() - camera_position.get_x(), get_top_left_y() - camera_position.get_y(), get_width(), get_height()); tile_pattern.fill_surface(get_map().get_visible_surface(), dst_position, get_map().get_tileset(), camera_position); }
/** * \brief Returns where the previous map should be blitted on * both_maps_surface, for the specified scrolling direction. * \param scrolling_direction The scrolling direction (0 to 3). */ Rectangle TransitionScrolling::get_previous_map_dst_position( int scrolling_direction) { const Size& quest_size = Video::get_quest_size(); Rectangle dst_position(0, 0); if (scrolling_direction == 1) { // Scroll to the north. dst_position.set_y(quest_size.height); } else if (scrolling_direction == 2) { // Scroll to the west. dst_position.set_x(quest_size.width); } return dst_position; }
/** * \brief Draws the tile on the specified surface. * \param dst_surface the destination surface * \param viewport coordinates of the top-left corner of dst_surface * relative to the map */ void Tile::draw(const SurfacePtr& dst_surface, const Point& viewport) { Rectangle dst_position( get_top_left_x() - viewport.x, get_top_left_y() - viewport.y, get_width(), get_height() ); tile_pattern.fill_surface( dst_surface, dst_position, get_map().get_tileset(), viewport ); }
/** * \brief Implementation of drawable:draw_region(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::drawable_api_draw_region(lua_State* l) { Drawable& drawable = check_drawable(l, 1); Rectangle region( luaL_checkint(l, 2), luaL_checkint(l, 3), luaL_checkint(l, 4), luaL_checkint(l, 5) ); Surface& dst_surface = check_surface(l, 6); Rectangle dst_position( luaL_optint(l, 7, 0), luaL_optint(l, 8, 0) ); drawable.draw_region(region, dst_surface, dst_position); return 0; }
/** * \brief Draws the tile on the map. */ void DynamicTile::draw_on_map() { const CameraPtr& camera = get_map().get_camera(); if (camera == nullptr) { return; } const Rectangle& camera_position = camera->get_bounding_box(); Rectangle dst_position(get_top_left_x() - camera_position.get_x(), get_top_left_y() - camera_position.get_y(), get_width(), get_height()); tile_pattern.fill_surface( get_map().get_camera_surface(), dst_position, get_map().get_tileset(), camera_position.get_xy() ); }
/** * \brief Redraws the text surface in the case of a bitmap font. * * This function is called when there is a change. */ void TextSurface::rebuild_bitmap() { // First count the number of characters in the UTF-8 string. int num_chars = 0; for (unsigned i = 0; i < text.size(); i++) { char current_char = text[i]; if ((current_char & 0xE0) == 0xC0) { // This character uses two bytes. ++i; } ++num_chars; } // Determine the letter size from the surface size. Surface& bitmap = *fonts[font_id].bitmap; const Rectangle& bitmap_size = bitmap.get_size(); int char_width = bitmap_size.get_width() / 128; int char_height = bitmap_size.get_height() / 16; surface = new Surface(char_width * num_chars, char_height); surface->set_transparency_color(bitmap.get_transparency_color()); // Traverse the string again to draw the characters. Rectangle dst_position(0, 0); for (unsigned i = 0; i < text.size(); i++) { char first_byte = text[i]; Rectangle src_position(0, 0, char_width, char_height); if ((first_byte & 0xE0) != 0xC0) { // This character uses one byte. src_position.set_xy(first_byte * char_width, 0); } else { // This character uses two bytes. ++i; char second_byte = text[i]; uint16_t code_point = ((first_byte & 0x1F) << 6) | (second_byte & 0x3F); src_position.set_xy((code_point % 128) * char_width, (code_point / 128) * char_height); } bitmap.draw_region(src_position, *surface, dst_position); dst_position.add_x(char_width - 1); } }