Exemple #1
0
void part_ui::render_background()
{
#if SDL_VERSION_ATLEAST(2,0,0)
	sdl::draw_solid_tinted_rectangle(
			0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0,
			video_.getSurface()
	);
	sdl_blit(background_, NULL, video_.getSurface(), NULL);
#else
#ifdef SDL_GPU
	GPU_Target *target = get_render_target();
	GPU_Clear(target);
	for (size_t i = 0; i<background_images_.size(); i++) {
		const int x = background_positions_[i].first;
		const int y = background_positions_[i].second;

		background_images_[i].draw(video_, x, y);
	}
#else
	sdl::draw_solid_tinted_rectangle(
		0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0,
		video_.getSurface()
	);
	sdl_blit(background_, NULL, video_.getSurface(), NULL);
#endif
#endif
}
void dialog_frame::draw_background()
{
	if(auto_restore_) {
		clear_background();
		restorer_ = new surface_restorer(&video_, dim_.exterior);
	}

	if (dialog_style_.blur_radius) {
		surface surf = ::get_surface_portion(video_.getSurface(), dim_.exterior);
		surf = blur_surface(surf, dialog_style_.blur_radius, false);
		sdl_blit(surf, NULL, video_.getSurface(), &dim_.exterior);
	}

	if(bg_ == NULL) {
		ERR_DP << "could not find dialog background '" << dialog_style_.panel << "'\n";
		return;
	}
	for(int i = 0; i < dim_.interior.w; i += bg_->w) {
		for(int j = 0; j < dim_.interior.h; j += bg_->h) {
			SDL_Rect src = {0,0,0,0};
			src.w = std::min(dim_.interior.w - i, bg_->w);
			src.h = std::min(dim_.interior.h - j, bg_->h);
			SDL_Rect dst = src;
			dst.x = dim_.interior.x + i;
			dst.y = dim_.interior.y + j;
			sdl_blit(bg_, &src, video_.getSurface(), &dst);
		}
	}
}
Exemple #3
0
void mouse_action::set_terrain_mouse_overlay(editor_display& disp, t_translation::t_terrain fg,
		t_translation::t_terrain bg)
{
	surface image_fg(image::get_image("terrain/"
		+ disp.get_map().get_terrain_info(fg).editor_image() + ".png"));
	surface image_bg(image::get_image("terrain/"
		+ disp.get_map().get_terrain_info(bg).editor_image() + ".png"));

	if (image_fg == NULL || image_bg == NULL) {
		ERR_ED << "Missing terrain icon\n";
		disp.set_mouseover_hex_overlay(NULL);
		return;
	}

	// Create a transparent surface of the right size.
	surface image = create_compatible_surface(image_fg, image_fg->w, image_fg->h);
	sdl_fill_rect(image,NULL,SDL_MapRGBA(image->format,0,0,0, 0));

	// For efficiency the size of the tile is cached.
	// We assume all tiles are of the same size.
	// The zoom factor can change, so it's not cached.
	// NOTE: when zooming and not moving the mouse, there are glitches.
	// Since the optimal alpha factor is unknown, it has to be calculated
	// on the fly, and caching the surfaces makes no sense yet.
	static const Uint8 alpha = 196;
	static const int size = image_fg->w;
	static const int half_size = size / 2;
	static const int quarter_size = size / 4;
	static const int offset = 2;
	static const int new_size = half_size - 2;
	const int zoom = static_cast<int>(size * disp.get_zoom_factor());

	// Blit left side
	image_fg = scale_surface(image_fg, new_size, new_size);
	SDL_Rect rcDestLeft = create_rect(offset, quarter_size, 0, 0);
	sdl_blit ( image_fg, NULL, image, &rcDestLeft );

	// Blit left side
	image_bg = scale_surface(image_bg, new_size, new_size);
	SDL_Rect rcDestRight = create_rect(half_size, quarter_size, 0, 0);
	sdl_blit ( image_bg, NULL, image, &rcDestRight );

	//apply mask so the overlay is contained within the mouseover hex
	image = mask_surface(image, image::get_hexmask());

	// Add the alpha factor and scale the image
	image = scale_surface(adjust_surface_alpha(image, alpha), zoom, zoom);

	// Set as mouseover
	disp.set_mouseover_hex_overlay(image);
}
void floating_label::draw(surface screen)
{
	if(!visible_) {
		buf_.assign(nullptr);
		return;
	}

	if(screen == nullptr) {
		return;
	}

	create_surface();
	if(surf_ == nullptr) {
		return;
	}

	if(buf_ == nullptr) {
		buf_.assign(create_compatible_surface(screen, surf_->w, surf_->h));
		if(buf_ == nullptr) {
			return;
		}
	}

	SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h);
	const clip_rect_setter clip_setter(screen, &clip_rect_);
	sdl_copy_portion(screen,&rect,buf_,nullptr);
	sdl_blit(surf_,nullptr,screen,&rect);
}
void textbox::draw_contents()
{
	SDL_Rect const &loc = inner_location();

	surface surf = video().getSurface();
	draw_solid_tinted_rectangle(loc.x,loc.y,loc.w,loc.h,0,0,0,
				    focus(NULL) ? alpha_focus_ : alpha_, surf);

	SDL_Rect src;

	if(text_image_ == NULL) {
		update_text_cache(true);
	}

	if(text_image_ != NULL) {
		src.y = yscroll_;
		src.w = std::min<size_t>(loc.w,text_image_->w);
		src.h = std::min<size_t>(loc.h,text_image_->h);
		src.x = text_pos_;
		SDL_Rect dest = screen_area();
		dest.x = loc.x;
		dest.y = loc.y;

		// Fills the selected area
		if(is_selection()) {
			const int start = std::min<int>(selstart_,selend_);
			const int end = std::max<int>(selstart_,selend_);
			int startx = char_x_[start];
			int starty = char_y_[start];
			const int endx = char_x_[end];
			const int endy = char_y_[end];

			while(starty <= endy) {
				const size_t right = starty == endy ? endx : text_image_->w;
				if(right <= size_t(startx)) {
					break;
				}

				SDL_Rect rect = create_rect(loc.x + startx
						, loc.y + starty - src.y
						, right - startx
						, line_height_);

				const clip_rect_setter clipper(surf, &loc);

				Uint32 color = SDL_MapRGB(surf->format, 0, 0, 160);
				fill_rect_alpha(rect, color, 140, surf);

				starty += int(line_height_);
				startx = 0;
			}
		}

		sdl_blit(text_image_, &src, surf, &dest);
	}

	draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());

	update_rect(loc);
}
void help_text_area::draw_contents()
{
	SDL_Rect const &loc = inner_location();
	bg_restore();
	surface screen = video().getSurface();
	clip_rect_setter clip_rect_set(screen, &loc);
	for(std::list<item>::const_iterator it = items_.begin(), end = items_.end(); it != end; ++it) {
		SDL_Rect dst = it->rect;
		dst.y -= get_position();
		if (dst.y < static_cast<int>(loc.h) && dst.y + it->rect.h > 0) {
			dst.x += loc.x;
			dst.y += loc.y;
			if (it->box) {
				for (int i = 0; i < box_width; ++i) {
					sdl::draw_rectangle(dst.x, dst.y, it->rect.w - i * 2, it->rect.h - i * 2,
					                    0, screen);
					++dst.x;
					++dst.y;
				}
			}
			sdl_blit(it->surf, NULL, screen, &dst);
		}
	}
	update_rect(loc);
}
Exemple #7
0
void halo_impl::effect::unrender()
{
	if (!surf_ || !buffer_) {
		return;
	}

	// Shrouded haloes are never rendered unless shroud has been re-placed; in
	// that case, unrendering causes the hidden terrain (and previous halo
	// frame, when dealing with animated halos) to glitch through shroud. We
	// don't need to unrender them because shroud paints over the underlying
	// area anyway.
	if (loc_.x != -1 && loc_.y != -1 && disp->shrouded(loc_)) {
		return;
	}

	surface& screen = disp->get_screen_surface();

	SDL_Rect clip_rect = disp->map_outside_area();
	const clip_rect_setter clip_setter(screen, &clip_rect);

	// Due to scrolling, the location of the rendered halo
	// might have changed; recalculate
	const int screenx = disp->get_location_x(map_location::ZERO());
	const int screeny = disp->get_location_y(map_location::ZERO());

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = sdl::create_rect(xpos, ypos, surf_->w, surf_->h);
	sdl_blit(buffer_,nullptr,screen,&rect);
	update_rect(rect);
}
Exemple #8
0
void unit_palette::draw_item(SDL_Rect& dstrect, const unit_type& u, std::stringstream& tooltip_text) {

	surface screen = gui_.video().getSurface();

	const std::string filename = u.image();
	surface image(image::get_image(filename));
	if(image == NULL) {
		tooltip_text << "IMAGE NOT FOUND\n";
		ERR_ED << "image for terrain: '" << filename << "' not found\n";
		image = image::get_image(game_config::images::missing);
		if (image == NULL) {
			ERR_ED << "Placeholder image not found\n";
			return;
		}
	}

	if(image->w != item_size_ || image->h != item_size_) {
		image.assign(scale_surface(image,
				item_size_, item_size_));
	}

	sdl_blit(image, NULL, screen, &dstrect);

	tooltip_text << u.type_name();
}
bool part_ui::render_floating_images()
{
	events::raise_draw_event();
	update_whole_screen();

	skip_ = false;
	last_key_ = true;

	size_t fi_n = 0;
	foreach(floating_image::render_input& ri, imgs_) {
		const floating_image& fi = p_.get_floating_images()[fi_n];

		if(!ri.image.null()) {
			sdl_blit(ri.image, NULL, video_.getSurface(), &ri.rect);
			update_rect(ri.rect);
		}

		if (!skip_)
		{
			int delay = fi.display_delay(), delay_step = 20;
			for (int i = 0; i != (delay + delay_step - 1) / delay_step; ++i)
			{
				if (handle_interface()) return false;
				if (skip_) break;
				disp_.delay(std::min<int>(delay_step, delay - i * delay_step));
			}
		}

		++fi_n;
	}

	return true;
}
void part_ui::render_background()
{
	draw_solid_tinted_rectangle(
		0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0,
		video_.getSurface()
	);
	sdl_blit(background_, NULL, video_.getSurface(), &base_rect_);
}
Exemple #11
0
void CVideo::blit_surface(int x, int y, surface surf, SDL_Rect* srcrect, SDL_Rect* clip_rect)
{
	surface target(getSurface());
	SDL_Rect dst = create_rect(x, y, 0, 0);

	const clip_rect_setter clip_setter(target, clip_rect, clip_rect != NULL);
	sdl_blit(surf,srcrect,target,&dst);
}
surface darken_function::operator()(const surface &src) const
{
	surface ret = make_neutral_surface(src);
	surface tod_dark(image::get_image(game_config::images::tod_dark));
	if (tod_dark)
		sdl_blit(tod_dark, NULL, ret, NULL);
	return ret;
}
surface mask_function::operator()(const surface& src) const
{
	if(src->w == mask_->w &&  src->h == mask_->h && x_ == 0 && y_ == 0)
		return mask_surface(src, mask_);
	SDL_Rect r = create_rect(x_, y_, 0, 0);
	surface new_mask = create_neutral_surface(src->w, src->h);
	sdl_blit(mask_, NULL, new_mask, &r);
	return mask_surface(src, new_mask);
}
Exemple #14
0
void surface_restorer::restore() const
{
	if(surface_.null()) {
		return;
	}

	SDL_Rect dst = rect_;
	sdl_blit(surface_, nullptr, target_->getSurface(), &dst);
}
surface blit_function::operator()(const surface& src) const
{
	//blit_surface want neutral surfaces
	surface nsrc = make_neutral_surface(src);
	surface nsurf = make_neutral_surface(surf_);
	SDL_Rect r = create_rect(x_, y_, 0, 0);
	sdl_blit(nsurf, NULL, nsrc, &r);
	return nsrc;
}
Exemple #16
0
void part_ui::render_background()
{
	sdl::draw_solid_tinted_rectangle(
			0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0,
			video_.getSurface()
	);
	sdl_blit(background_, NULL, video_.getSurface(), NULL);
	// Render the titlebox over the background
	render_title_box();
}
void textbox::append_text(const std::string& text, bool auto_scroll, const SDL_Color& color)
{
	if(text_image_.get() == NULL) {
		set_text(text, color);
		return;
	}

	//disallow adding multi-line text to a single-line text box
	if(wrap_ == false && std::find_if(text.begin(),text.end(),utils::isnewline) != text.end()) {
		return;
	}
	const bool is_at_bottom = get_position() == get_max_position();
	const wide_string& wtext = utils::string_to_wstring(text);

	const surface new_text = add_text_line(wtext, color);
	surface new_surface = create_compatible_surface(text_image_,std::max<size_t>(text_image_->w,new_text->w),text_image_->h+new_text->h);

	SDL_SetAlpha(new_text.get(),0,0);
	SDL_SetAlpha(text_image_.get(),0,0);

	sdl_blit(text_image_,NULL,new_surface,NULL);

	SDL_Rect target = create_rect(0
			, text_image_->h
			, new_text->w
			, new_text->h);

	sdl_blit(new_text,NULL,new_surface,&target);
	text_image_.assign(new_surface);

	text_.resize(text_.size() + wtext.size());
	std::copy(wtext.begin(),wtext.end(),text_.end()-wtext.size());

	set_dirty(true);
	update_text_cache(false);
	if(auto_scroll && is_at_bottom) scroll_to_bottom();
	handle_text_changed(text_);
}
Exemple #18
0
void surface_restorer::restore(const SDL_Rect& dst) const
{
	if(surface_.null()) {
		return;
	}

	SDL_Rect dst2 = sdl::intersect_rects(dst, rect_);
	if(dst2.w == 0 || dst2.h == 0) {
		return;
	}

	SDL_Rect src = dst2;
	src.x -= rect_.x;
	src.y -= rect_.y;
	sdl_blit(surface_, &src, target_->getSurface(), &dst2);
}
void undraw(surface screen)
{
	if(use_color_cursors() == false) {
		return;
	}

	if(cursor_buf == NULL) {
		return;
	}

	SDL_Rect area = create_rect(cursor_x - shift_x[current_cursor]
			, cursor_y - shift_y[current_cursor]
			, cursor_buf->w
			, cursor_buf->h);
	sdl_blit(cursor_buf,NULL,screen,&area);
	update_rect(area);
}
Exemple #20
0
void ttrack::impl_draw_background(surface& frame_buffer, int x_offset, int y_offset)
{
	tcontrol::impl_draw_background(frame_buffer, x_offset, y_offset);

	SDL_Rect rc = get_rect();
	if (!background_surf_ || background_surf_->w != w_ || background_surf_->h != h_) {
		background_surf_.assign(get_surface_portion(frame_buffer, rc));
	} else {
		sdl_blit(frame_buffer, &rc, background_surf_, NULL);
	}

	frame_buffer_ = frame_buffer;
	frame_offset_ = tpoint(x_offset + draw_offset_.x, y_offset + draw_offset_.y);
	if (callback_timer_) {
		callback_timer_(*this, frame_buffer, frame_offset_, state2_, false);
	}
}
void floating_label::undraw(surface screen)
{
	if(screen == nullptr || buf_ == nullptr) {
		return;
	}
	SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h);
	const clip_rect_setter clip_setter(screen, &clip_rect_);
	sdl_blit(buf_,nullptr,screen,&rect);

	move(xmove_,ymove_);
	if(lifetime_ > 0) {
		--lifetime_;
		if(alpha_change_ != 0 && (xmove_ != 0.0 || ymove_ != 0.0) && surf_ != nullptr) {
			// fade out moving floating labels
			surf_.assign(adjust_surface_alpha_add(surf_,alpha_change_));
		}
	}
}
void fill_rect_alpha(SDL_Rect &rect, Uint32 color, Uint8 alpha, surface target)
{
	if(alpha == SDL_ALPHA_OPAQUE) {
		sdl::fill_rect(target,&rect,color);
		return;
	} else if(alpha == SDL_ALPHA_TRANSPARENT) {
		return;
	}

	surface tmp(create_compatible_surface(target,rect.w,rect.h));
	if(tmp == NULL) {
		return;
	}

	SDL_Rect r = {0,0,rect.w,rect.h};
	sdl::fill_rect(tmp,&r,color);
	SDL_SetAlpha(tmp,SDL_SRCALPHA,alpha);
	sdl_blit(tmp,NULL,target,&rect);
}
Exemple #23
0
void tminimap::impl_draw_background(surface& frame_buffer)
{
	if(!terrain_)
		return;
	assert(terrain_);

	DBG_GUI_D << LOG_HEADER << " size " << get_rectangle() << ".\n";

	if(map_data_.empty()) {
		return;
	}

	SDL_Rect rect = get_rectangle();
	assert(rect.w > 0 && rect.h > 0);

	const ::surface surf = get_image(rect.w, rect.h);
	if(surf) {
		sdl_blit(surf, NULL, frame_buffer, &rect);
	}
}
Exemple #24
0
void effect::unrender()
{
	if (!surf_ || !buffer_) {
		return;
	}

	surface screen = disp->get_screen_surface();

	SDL_Rect clip_rect = disp->map_outside_area();
	const clip_rect_setter clip_setter(screen, &clip_rect);

	// Due to scrolling, the location of the rendered halo
	// might have changed; recalculate
	const map_location zero_loc(0,0);
	const int screenx = disp->get_location_x(zero_loc);
	const int screeny = disp->get_location_y(zero_loc);

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = create_rect(xpos, ypos, surf_->w, surf_->h);
	sdl_blit(buffer_,NULL,screen,&rect);
}
Exemple #25
0
void tminimap::impl_draw_background(surface& frame_buffer,
									int x_offset,
									int y_offset)
{
	if(!terrain_)
		return;
	assert(terrain_);

	DBG_GUI_D << LOG_HEADER << " size "
			  << calculate_blitting_rectangle(x_offset, y_offset) << ".\n";

	if(map_data_.empty()) {
		return;
	}

	SDL_Rect rect = calculate_blitting_rectangle(x_offset, y_offset);
	assert(rect.w > 0 && rect.h > 0);

	const ::surface surf = get_image(rect.w, rect.h);
	if(surf) {
		sdl_blit(surf, nullptr, frame_buffer, &rect);
	}
}
void draw(surface screen)
{
	if(use_color_cursors() == false) {
		return;
	}

	if(current_cursor == NUM_CURSORS) {
		current_cursor = NORMAL;
	}

	if(have_focus == false) {
		cursor_buf = NULL;
		return;
	}

	if (!color_ready) {
		// Display start to draw cursor
		// so it can now display color cursor
		color_ready = true;
		// Reset the cursor to be sure that we hide the b&w
		set();
	}

	/** @todo FIXME: don't parse the file path every time */
	const surface surf(image::get_image("cursors/" + color_images[current_cursor]));
	if(surf == NULL) {
		// Fall back to b&w cursors
		std::cerr << "could not load color cursors. Falling back to hardware cursors\n";
		preferences::set_color_cursors(false);
		return;
	}

	if(cursor_buf != NULL && (cursor_buf->w != surf->w || cursor_buf->h != surf->h)) {
		cursor_buf = NULL;
	}

	if(cursor_buf == NULL) {
		cursor_buf = create_compatible_surface(surf);
		if(cursor_buf == NULL) {
			std::cerr << "Could not allocate surface for mouse cursor\n";
			return;
		}
	}

	int new_cursor_x, new_cursor_y;
	SDL_GetMouseState(&new_cursor_x,&new_cursor_y);
	const bool must_update = new_cursor_x != cursor_x || new_cursor_y != cursor_y;
	cursor_x = new_cursor_x;
	cursor_y = new_cursor_y;

	// Save the screen area where the cursor is being drawn onto the back buffer
	SDL_Rect area = create_rect(cursor_x - shift_x[current_cursor]
			, cursor_y - shift_y[current_cursor]
			, surf->w
			, surf->h);
	sdl_blit(screen,&area,cursor_buf,NULL);

	// Blit the surface
	sdl_blit(surf,NULL,screen,&area);

	if(must_update) {
		update_rect(area);
	}
}
Exemple #27
0
surface getMinimap(int w, int h, const gamemap &map, const team *vw)
{
	const int scale = 8;

	DBG_DP << "creating minimap " << int(map.w()*scale*0.75) << "," << map.h()*scale << "\n";

	const size_t map_width = map.w()*scale*3/4;
	const size_t map_height = map.h()*scale;
	if(map_width == 0 || map_height == 0) {
		return surface(NULL);
	}

	surface minimap(create_neutral_surface(map_width, map_height));
	if(minimap == NULL)
		return surface(NULL);

	typedef mini_terrain_cache_map cache_map;
	cache_map *normal_cache = &mini_terrain_cache;
	cache_map *fog_cache = &mini_fogged_terrain_cache;

	for(int y = 0; y != map.total_height(); ++y) {
		for(int x = 0; x != map.total_width(); ++x) {

			surface surf(NULL);

			const map_location loc(x,y);
			if(map.on_board(loc)) {

				const bool shrouded = (vw != NULL && vw->shrouded(loc));
				// shrouded hex are not considered fogged (no need to fog a black image)
				const bool fogged = (vw != NULL && !shrouded && vw->fogged(loc));
				const t_translation::t_terrain terrain = shrouded ?
						t_translation::VOID_TERRAIN : map[loc];
				const terrain_type& terrain_info = map.get_terrain_info(terrain);

				bool need_fogging = false;

				cache_map* cache = fogged ? fog_cache : normal_cache;
				cache_map::iterator i = cache->find(terrain);

				if (fogged && i == cache->end()) {
					// we don't have the fogged version in cache
					// try the normal cache and ask fogging the image
					cache = normal_cache;
					i = cache->find(terrain);
					need_fogging = true;
				}

				if(i == cache->end()) {
					std::string base_file =
							"terrain/" + terrain_info.minimap_image() + ".png";
					surface tile = get_image(base_file,image::HEXED);

					//Compose images of base and overlay if necessary
					// NOTE we also skip overlay when base is missing (to avoid hiding the error)
					if(tile != NULL && map.get_terrain_info(terrain).is_combined()) {
						std::string overlay_file =
								"terrain/" + terrain_info.minimap_image_overlay() + ".png";
						surface overlay = get_image(overlay_file,image::HEXED);

						if(overlay != NULL && overlay != tile) {
							surface combined = create_neutral_surface(tile->w, tile->h);
							SDL_Rect r = create_rect(0,0,0,0);
							sdl_blit(tile, NULL, combined, &r);
							r.x = std::max(0, (tile->w - overlay->w)/2);
							r.y = std::max(0, (tile->h - overlay->h)/2);
							//blit_surface needs neutral surface
							surface overlay_neutral = make_neutral_surface(overlay);
							blit_surface(overlay_neutral, NULL, combined, &r);
							tile = combined;
						}
					}

					surf = scale_surface_sharp(tile, scale, scale);

					i = normal_cache->insert(cache_map::value_type(terrain,surf)).first;
				}

				surf = i->second;

				if (need_fogging) {
					surf = adjust_surface_color(surf,-50,-50,-50);
					fog_cache->insert(cache_map::value_type(terrain,surf));
				}

				// we need a balanced shift up and down of the hexes.
				// if not, only the bottom half-hexes are clipped
				// and it looks asymmetrical.

				// also do 1-pixel shift because the scaling
				// function seems to do it with its rounding
				SDL_Rect maprect = create_rect(
						  x * scale * 3 / 4 - 1
						, y * scale + scale / 4 * (is_odd(x) ? 1 : -1) - 1
						, 0
						, 0);

				if(surf != NULL)
					sdl_blit(surf, NULL, minimap, &maprect);
			}
		}
	}

	double wratio = w*1.0 / minimap->w;
	double hratio = h*1.0 / minimap->h;
	double ratio = std::min<double>(wratio, hratio);

	minimap = scale_surface_sharp(minimap,
		static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio));

	DBG_DP << "done generating minimap\n";

	return minimap;
}
Exemple #28
0
bool effect::render()
{
	if(disp == NULL) {
		return false;
	}

	if(loc_.x != -1 && loc_.y != -1) {
		if(disp->shrouded(loc_)) {
			return false;
		} else {
			// The location of a halo is an x,y value and not a map location.
			// This means when a map is zoomed, the halo's won't move,
			// This glitch is most visible on [item] haloes.
			// This workaround always recalculates the location of the halo
			// (item haloes have a location parameter to hide them under the shroud)
			// and reapplies that location.
			// It might be optimized by storing and comparing the zoom value.
			set_location(
				disp->get_location_x(loc_) + disp->hex_size() / 2,
				disp->get_location_y(loc_) + disp->hex_size() / 2);
		}
	}

	images_.update_last_draw_time();
	surf_.assign(image::get_image(current_image(),image::SCALED_TO_ZOOM));
	if(surf_ == NULL) {
		return false;
	}
	if(orientation_ == HREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(image::reverse_image(surf_));
	}
	if(orientation_ == VREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(flop_surface(surf_));
	}

	const map_location zero_loc(0,0);
	const int screenx = disp->get_location_x(zero_loc);
	const int screeny = disp->get_location_y(zero_loc);

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = create_rect(xpos, ypos, surf_->w, surf_->h);
	rect_ = rect;
	SDL_Rect clip_rect = disp->map_outside_area();

	// If rendered the first time, need to determine the area affected.
	// If a halo changes size, it is not updated.
	if(overlayed_hexes_.empty()) {
		rect_of_hexes hexes = disp->hexes_under_rect(rect);
		rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
		for (;i != end; ++i) {
			overlayed_hexes_.push_back(*i);
		}
	}

	if(rects_overlap(rect,clip_rect) == false) {
		buffer_.assign(NULL);
		return false;
	}

	surface screen = disp->get_screen_surface();

	const clip_rect_setter clip_setter(screen, &clip_rect);
	if(buffer_ == NULL || buffer_->w != rect.w || buffer_->h != rect.h) {
		SDL_Rect rect = rect_;
		buffer_.assign(get_surface_portion(screen,rect));
	} else {
		SDL_Rect rect = rect_;
		sdl_blit(screen,&rect,buffer_,NULL);
	}

	sdl_blit(surf_,NULL,screen,&rect);

	return true;
}
Exemple #29
0
void loadscreen::draw_screen(const std::string &text)
{
	// Set progress bar parameters:
	//
	// RGB-values for finished piece.
	int fcr =  21, fcg =  53, fcb =  80;
	// Groove.
	int lcr =  21, lcg =  22, lcb =  24;
	// Border color.
	int bcr = 188, bcg = 176, bcb = 136;
	// Border width.
	int bw = 1;
	// Border inner spacing width.
	int bispw = 1;
	bw = 2*(bw+bispw) > screen_.getx() ? 0: 2*(bw+bispw) > screen_.gety() ? 0: bw;
	// Available width.
	int scrx = screen_.getx() - 2*(bw+bispw);
	// Available height.
	int scry = screen_.gety() - 2*(bw+bispw);
	// Used width.
	int pbw = scrx/2;
	// Used height.
	int pbh = scry/16;
	// Height of the lighting line.
	int	lightning_thickness = 2;

	surface gdis = screen_.getSurface();
	SDL_Rect area;

	// Pump events and make sure to redraw the logo if there's a chance that it's been obscured
	SDL_Event ev;
	while(SDL_PollEvent(&ev)) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
		if(ev.type == SDL_WINDOWEVENT
				&& (ev.window.event == SDL_WINDOWEVENT_RESIZED
					|| ev.window.event == SDL_WINDOWEVENT_EXPOSED))
#else
		if(ev.type == SDL_VIDEORESIZE || ev.type == SDL_VIDEOEXPOSE)
#endif
		{
			logo_drawn_ = false;
		}
	}

	// Draw logo if it was successfully loaded.
#if SDL_VERSION_ATLEAST(2,0,0)
	static int angle = 0;
	if (!logo_texture_.null() /*&& !logo_drawn_*/) {
		int x = (screen_.getx () - logo_texture_.width()) / 2;
		int y = ((scry - logo_texture_.height()) / 2) - pbh;

		// Check if we have enough pixels to display it.
		if (x > 0 && y > 0) {
			pby_offset_ = (pbh + logo_texture_.height())/2;
			CVideo::get_window()->draw(logo_texture_, x, y);
		} else {
			if (!screen_.faked()) {  // Avoid error if --nogui is used.
				ERR_DP << "loadscreen: Logo image is too big." << std::endl;
			}
		}
		logo_drawn_ = true;
		logo_texture_.set_rotation(angle+=3);
	}
#else
	if (logo_surface_ && !logo_drawn_) {
		area.x = (screen_.getx () - logo_surface_->w) / 2;
		area.y = ((scry - logo_surface_->h) / 2) - pbh;
		area.w = logo_surface_->w;
		area.h = logo_surface_->h;
		// Check if we have enough pixels to display it.
		if (area.x > 0 && area.y > 0) {
			pby_offset_ = (pbh + area.h)/2;
			sdl_blit(logo_surface_, 0, gdis, &area);
		} else {
			if (!screen_.faked()) {  // Avoid error if --nogui is used.
				ERR_DP << "loadscreen: Logo image is too big." << std::endl;
			}
		}
		logo_drawn_ = true;
		update_rect(area.x, area.y, area.w, area.h);
	}
#endif
	int pbx = (scrx - pbw)/2;					// Horizontal location.
	int pby = (scry - pbh)/2 + pby_offset_;		// Vertical location.

	// Draw top border.
	area.x = pbx; area.y = pby;
	area.w = pbw + 2*(bw+bispw); area.h = bw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw bottom border.
	area.x = pbx; area.y = pby + pbh + bw + 2*bispw;
	area.w = pbw + 2*(bw+bispw); area.h = bw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw left border.
	area.x = pbx; area.y = pby + bw;
	area.w = bw; area.h = pbh + 2*bispw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw right border.
	area.x = pbx + pbw + bw + 2*bispw; area.y = pby + bw;
	area.w = bw; area.h = pbh + 2*bispw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw the finished bar area.
	area.x = pbx + bw + bispw; area.y = pby + bw + bispw;
	area.w = (prcnt_ * pbw) / 100; area.h = pbh;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,fcr,fcg,fcb));

	SDL_Rect lightning = area;
	lightning.h = lightning_thickness;
	//we add 25% of white to the color of the bar to simulate a light effect
	sdl::fill_rect(gdis,&lightning,SDL_MapRGB(gdis->format,(fcr*3+255)/4,(fcg*3+255)/4,(fcb*3+255)/4));
	lightning.y = area.y+area.h-lightning.h;
	//remove 50% of color to simulate a shadow effect
	sdl::fill_rect(gdis,&lightning,SDL_MapRGB(gdis->format,fcr/2,fcg/2,fcb/2));

	// Draw the leftover bar area.
	area.x = pbx + bw + bispw + (prcnt_ * pbw) / 100; area.y = pby + bw + bispw;
	area.w = ((100 - prcnt_) * pbw) / 100; area.h = pbh;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,lcr,lcg,lcb));

	// Clear the last text and draw new if text is provided.
	if (!text.empty())
	{
		SDL_Rect oldarea = textarea_;
		sdl::fill_rect(gdis,&textarea_,SDL_MapRGB(gdis->format,0,0,0));
		textarea_ = font::line_size(text, font::SIZE_NORMAL);
		textarea_.x = scrx/2 + bw + bispw - textarea_.w / 2;
		textarea_.y = pby + pbh + 4*(bw + bispw);
		textarea_ = font::draw_text(&screen_,textarea_,font::SIZE_NORMAL,font::NORMAL_COLOR,text,textarea_.x,textarea_.y);
		SDL_Rect refresh = sdl::union_rects(oldarea, textarea_);
		update_rect(refresh.x, refresh.y, refresh.w, refresh.h);
	}
	// Update the rectangle.
	update_rect(pbx, pby, pbw + 2*(bw + bispw), pbh + 2*(bw + bispw));
	screen_.flip();
#if SDL_VERSION_ATLEAST(2,0,0)
	CVideo::get_window()->render();
#endif
}
surface floating_label::create_surface()
{
	if(surf_.null()) {
		font::pango_text text;
		text.set_foreground_color(color_);
		text.set_font_size(font_size_);
		text.set_maximum_width(width_ < 0 ? clip_rect_.w : width_);
		text.set_maximum_height(height_ < 0 ? clip_rect_.h : height_, true);

		// ignore last '\n'
		if(!text_.empty() && *(text_.rbegin()) == '\n') {
			text.set_text(std::string(text_.begin(), text_.end() - 1), use_markup_);
		} else {
			text.set_text(text_, use_markup_);
		}

		surface foreground = text.render();

		if(foreground == nullptr) {
			ERR_FT << "could not create floating label's text" << std::endl;
			return nullptr;
		}

		// combine foreground text with its background
		if(bgalpha_ != 0) {
			// background is a dark tooltip box
			surface background = create_neutral_surface(foreground->w + border_ * 2, foreground->h + border_ * 2);

			if(background == nullptr) {
				ERR_FT << "could not create tooltip box" << std::endl;
				return surf_ = foreground;
			}

			uint32_t color = SDL_MapRGBA(foreground->format, bgcolor_.r, bgcolor_.g, bgcolor_.b, bgalpha_);
			sdl::fill_surface_rect(background, nullptr, color);

			// we make the text less transparent, because the blitting on the
			// dark background will darken the anti-aliased part.
			// This 1.13 value seems to restore the brightness of version 1.4
			// (where the text was blitted directly on screen)
			adjust_surface_alpha(foreground, ftofxp(1.13));

			SDL_Rect r{border_, border_, 0, 0};
			adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
			sdl_blit(foreground, nullptr, background, &r);

			surf_ = background;
		} else {
			// background is blurred shadow of the text
			surface background = create_neutral_surface(foreground->w + 4, foreground->h + 4);
			sdl::fill_surface_rect(background, nullptr, 0);
			SDL_Rect r{2, 2, 0, 0};
			sdl_blit(foreground, nullptr, background, &r);
			background = shadow_image(background);

			if(background == nullptr) {
				ERR_FT << "could not create floating label's shadow" << std::endl;
				return surf_ = foreground;
			}
			sdl_blit(foreground, nullptr, background, &r);
			surf_ = background;
		}
	}

	return surf_;
}