コード例 #1
0
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;
}
コード例 #2
0
ファイル: wesmage.cpp プロジェクト: Martin9295/wesnoth
int
main(int argc, char* argv[])
{
	try {
		const toptions& options = toptions::parse(argc, argv);

		surface surf(make_neutral_surface(
				IMG_Load(options.input_filename.c_str())));

		if(!surf) {
			std::cerr << "Error: Failed to load input file »"
					<< options.input_filename
					<< "«.\n";

			return EXIT_FAILURE;
		}

		std::vector<surface> surfaces;
		if(options.count != 1) {
			for(int i = 1; i < options.count; ++i) {
				// make_neutral_surface make a deep-copy of the image.
				surfaces.push_back(make_neutral_surface(surf));
			}
		}
		surfaces.push_back(surf);

		const clock_t begin = options.time ? get_begin_time() : 0;

		for(int i = 0; i < options.count; ++i) {
			BOOST_FOREACH(const std::string& filter, options.filters) {
				filter_apply(surfaces[i], filter);
			}
		}

		if(options.time) {
			const clock_t end = std::clock();
			std::cout << "Applying the filters took "
					<<  end - begin
					<< " ticks, "
					<< static_cast<double>(end - begin) / CLOCKS_PER_SEC
					<< " seconds.\n";
		}

		if(!options.output_filename.empty()) {
			save_image(surfaces[0], options.output_filename);
		}

	} catch(const texit& exit) {
		return exit.status;
	} catch(exploder_failure& err) {
		std::cerr << "Error: Failed with error »" << err.message << "«.\n";
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
コード例 #3
0
surface crop_modification::operator()(const surface& src) const
{
	SDL_Rect area = slice_;
	if(area.w == 0) {
		area.w = src->w;
	}
	if(area.h == 0) {
		area.h = src->h;
	}
	if(area.x < 0) {
		ERR_DP << "start X coordinate of CROP modification is negative - truncating to zero\n";
		area.x = 0;
	}
	if(area.y < 0) {
		ERR_DP << "start Y coordinate of CROP modification is negative - truncating to zero\n";
		area.y = 0;
	}

	/*
	 * Unlike other image functions cut_surface does not convert the input
	 * surface to a neutral surface, nor does it convert its return surface
	 * to an optimised surface.
	 *
	 * Since it seems to work for most cases, rather change this caller instead
	 * of the function signature. (The issue was discovered in bug #20876).
	 */
	return create_optimized_surface(
			cut_surface(make_neutral_surface(src), area));
}
コード例 #4
0
surface darken_modification::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)
		blit_surface(tod_dark, NULL, ret, NULL);
	return ret;
}
コード例 #5
0
surface brighten_function::operator()(const surface &src) const
{
	surface ret = make_neutral_surface(src);
	surface tod_bright(image::get_image(game_config::images:: tod_bright));
	if (tod_bright)
		sdl_blit(tod_bright, NULL, ret, NULL);
	return ret;
}
コード例 #6
0
surface blit_modification::operator()(const surface& src) const
{
	if(x_ >= src->w) {
		std::stringstream sstr;
		sstr << "~BLIT(): x-coordinate '"
			<< x_ << "' larger than destination image's width '"
			<< src->w << "' no blitting performed.\n";

		throw texception(sstr);
	}

	if(y_ >= src->h) {
		std::stringstream sstr;
		sstr << "~BLIT(): y-coordinate '"
			<< y_ << "' larger than destination image's height '"
			<< src->h << "' no blitting performed.\n";

		throw texception(sstr);
	}

	if(surf_->w + x_ > src->w) {
		std::stringstream sstr;
		sstr << "~BLIT(): offset and width '"
			<< x_ + surf_->w << "' larger than destination image's width '"
			<< src->w << "' no blitting performed.\n";

		throw texception(sstr);
	}

	if(surf_->h + y_ > src->h) {
		std::stringstream sstr;
		sstr << "~BLIT(): offset and height '"
			<< y_ + surf_->h << "' larger than destination image's height '"
			<< src->h << "' no blitting performed.\n";

		throw texception(sstr);
	}

	//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);
	blit_surface(nsurf, NULL, nsrc, &r);
	return nsrc;
}
コード例 #7
0
surface background_modification::operator()(const surface &src) const
{
	surface ret = make_neutral_surface(src);
	SDL_FillRect(ret, NULL, SDL_MapRGBA(ret->format, color_.r, color_.g,
					    color_.b, color_.unused));
	SDL_SetAlpha(src, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
	SDL_BlitSurface(src, NULL, ret, NULL);
	return ret;
}
コード例 #8
0
surface light_modification::operator()(const surface& src) const {
	if(src == NULL) { return NULL; }

	//light_surface wants a neutral surface having same dimensions
	surface nsurf;
	if(surf_->w != src->w || surf_->h != src->h)
		nsurf = scale_surface(surf_, src->w, src->h, false);
	else
		nsurf = make_neutral_surface(surf_);
	return light_surface(src, nsurf);;
}
コード例 #9
0
surface background_modification::operator()(const surface &src) const
{
	surface ret = make_neutral_surface(src);
#if SDL_VERSION_ATLEAST(2,0,0)
	SDL_FillRect(ret, NULL, SDL_MapRGBA(ret->format, color_.r, color_.g,
					    color_.b, color_.a));
#else
	SDL_FillRect(ret, NULL, SDL_MapRGBA(ret->format, color_.r, color_.g,
					    color_.b, color_.unused));
#endif
	SDL_SetAlpha(src, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
	blit_surface(src, NULL, ret, NULL);
	return ret;
}
コード例 #10
0
void cutter::load_masks(const config& conf)
{
	const config::child_list& masks = conf.get_children("mask");

	for(config::child_list::const_iterator itor = masks.begin();
		       itor != masks.end(); ++itor) {

		const std::string name = (**itor)["name"];
		const std::string image = get_mask_dir() + "/" + (**itor)["image"];

		if(verbose_) {
			std::cerr << "Adding mask " << name << "\n";
		}

		if(image.empty())
			throw exploder_failure("Missing image for mask " + name);

		const exploder_point shift((**itor)["shift"]);
		const exploder_rect cut((**itor)["cut"]);

		if(masks_.find(name) != masks_.end() && masks_[name].filename != image) {
			throw exploder_failure("Mask " + name +
					" correspond to two different files: " +
					name + " and " +
					masks_.find(name)->second.filename);
		}

		if(masks_.find(name) == masks_.end()) {
			mask& cur_mask = masks_[name];

			cur_mask.name = name;
			cur_mask.shift = shift;
			cur_mask.cut = cut;
			cur_mask.filename = image;
			surface tmp(IMG_Load(image.c_str()));
			if(tmp == NULL)
				throw exploder_failure("Unable to load mask image " + image);

			cur_mask.image = surface(make_neutral_surface(tmp));
		}

		if(masks_[name].image == NULL)
			throw exploder_failure("Unable to load mask image " + image);
	}
}
コード例 #11
0
void cutter::load_masks(const config& conf)
{
	BOOST_FOREACH(const config &m, conf.child_range("mask"))
	{
		const std::string name = m["name"];
		const std::string image = get_mask_dir() + "/" + std::string(m["image"]);

		if(verbose_) {
			std::cerr << "Adding mask " << name << "\n";
		}

		if(image.empty())
			throw exploder_failure("Missing image for mask " + name);

		const exploder_point shift(m["shift"]);
		const exploder_rect cut(m["cut"]);

		if(masks_.find(name) != masks_.end() && masks_[name].filename != image) {
			throw exploder_failure("Mask " + name +
					" correspond to two different files: " +
					name + " and " +
					masks_.find(name)->second.filename);
		}

		if(masks_.find(name) == masks_.end()) {
			mask& cur_mask = masks_[name];

			cur_mask.name = name;
			cur_mask.shift = shift;
			cur_mask.cut = cut;
			cur_mask.filename = image;
			surface tmp(IMG_Load(image.c_str()));
			if(tmp == NULL)
				throw exploder_failure("Unable to load mask image " + image);

			cur_mask.image = surface(make_neutral_surface(tmp));
		}

		if(masks_[name].image == NULL)
			throw exploder_failure("Unable to load mask image " + image);
	}
}
コード例 #12
0
ファイル: drawer.cpp プロジェクト: ArtBears/wesnoth
const SDL_Rect& unit_drawer::calculate_energy_bar(surface surf) const
{
	const std::map<surface,SDL_Rect>::const_iterator i = energy_bar_rects_.find(surf);
	if(i != energy_bar_rects_.end()) {
		return i->second;
	}

	int first_row = -1, last_row = -1, first_col = -1, last_col = -1;

	surface image(make_neutral_surface(surf));

	const_surface_lock image_lock(image);
	const Uint32* const begin = image_lock.pixels();

	for(int y = 0; y != image->h; ++y) {
		const Uint32* const i1 = begin + image->w*y;
		const Uint32* const i2 = i1 + image->w;
		const Uint32* const itor = std::find_if(i1,i2,is_energy_color());
		const int count = std::count_if(itor,i2,is_energy_color());

		if(itor != i2) {
			if(first_row == -1) {
				first_row = y;
			}

			first_col = itor - i1;
			last_col = first_col + count;
			last_row = y;
		}
	}

	const SDL_Rect res = sdl::create_rect(first_col
			, first_row
			, last_col-first_col
			, last_row+1-first_row);
	energy_bar_rects_.insert(std::pair<surface,SDL_Rect>(surf,res));
	return calculate_energy_bar(surf);
}
コード例 #13
0
ファイル: button.cpp プロジェクト: AI0867/wesnoth
void button::draw_contents()
{
	surface image = image_;
	const int image_w = image_->w;

	int offset = 0;
	switch(state_) {
	case ACTIVE:
		image = activeImage_;
		break;
	case PRESSED:
		image = pressedImage_;
		if (type_ == TYPE_PRESS)
			offset = 1;
		break;
	case PRESSED_ACTIVE:
		image = pressedActiveImage_;
		break;
	case TOUCHED_NORMAL:
	case TOUCHED_PRESSED:
		image = touchedImage_;
		break;
	default:
		break;
	}

	SDL_Rect const &loc = location();
	SDL_Rect clipArea = loc;
	const int texty = loc.y + loc.h / 2 - textRect_.h / 2 + offset;
	int textx;

	if (type_ != TYPE_CHECK && type_ != TYPE_RADIO && type_ != TYPE_IMAGE)
		textx = loc.x + image->w / 2 - textRect_.w / 2 + offset;
	else {
		clipArea.w += image_w + checkbox_horizontal_padding;
		textx = loc.x + image_w + checkbox_horizontal_padding / 2;
	}

	SDL_Color button_color = font::BUTTON_COLOR;

	if (!enabled()) {

		if (state_ == PRESSED || state_ == PRESSED_ACTIVE)
			image = pressedDisabledImage_;
		else image = disabledImage_;

		button_color = font::GRAY_COLOR;
	}

	if (!overlayImage_.null()) {

		surface noverlay = make_neutral_surface(
				enabled() ? overlayImage_ : overlayDisabledImage_);

		if (!overlayPressedImage_.null()) {
			switch (state_) {
			case ACTIVE:
				if (!overlayActiveImage_.null())
					noverlay = make_neutral_surface(overlayActiveImage_);
				break;
			case PRESSED:
			case PRESSED_ACTIVE:
			case TOUCHED_NORMAL:
			case TOUCHED_PRESSED:
				noverlay = make_neutral_surface( enabled() ?
						overlayPressedImage_ : overlayPressedDisabledImage_);
				break;
			default:
				break;
			}
		}

		surface nimage = make_neutral_surface(image);
		blit_surface(noverlay, NULL, nimage, NULL);
		image = nimage;
	}

	video().blit_surface(loc.x, loc.y, image);
	if (type_ != TYPE_IMAGE){
		clipArea.x += offset;
		clipArea.y += offset;
		clipArea.w -= 2*offset;
		clipArea.h -= 2*offset;
		font::draw_text(&video(), clipArea, font_size, button_color, label_, textx, texty);
	}

	update_rect(loc);
}
コード例 #14
0
void timage::draw(surface& canvas
		, const game_logic::map_formula_callable& variables)
{
	DBG_GUI_D << "Image: draw.\n";

	/**
	 * @todo formulas are now recalculated every draw cycle which is a  bit
	 * silly unless there has been a resize. So to optimize we should use an
	 * extra flag or do the calculation in a separate routine.
	 */
	const std::string& name = image_name_(variables);

	if(name.empty()) {
		DBG_GUI_D << "Image: formula returned no value, will not be drawn.\n";
		return;
	}

	/*
	 * The locator might return a different surface for every call so we can't
	 * cache the output, also not if no formula is used.
	 */
	surface tmp(image::get_image(image::locator(name)));

	if(!tmp) {
		ERR_GUI_D << "Image: '" << name << "' not found and won't be drawn.\n";
		return;
	}

	image_.assign(make_neutral_surface(tmp));
	assert(image_);
	src_clip_ = ::create_rect(0, 0, image_->w, image_->h);

	game_logic::map_formula_callable local_variables(variables);
	local_variables.add("image_original_width", variant(image_->w));
	local_variables.add("image_original_height", variant(image_->h));

	unsigned w = w_(local_variables);
	VALIDATE_WITH_DEV_MESSAGE(
			  static_cast<int>(w) >= 0
			, _("Image doesn't fit on canvas.")
			, (formatter() << "Image '" << name
				<< "', w = " << static_cast<int>(w) << ".").str());

	unsigned h = h_(local_variables);
	VALIDATE_WITH_DEV_MESSAGE(
			  static_cast<int>(h) >= 0
			, _("Image doesn't fit on canvas.")
			, (formatter() << "Image '" << name
				<< "', h = " << static_cast<int>(h) << ".").str());

	local_variables.add("image_width", variant(w ? w : image_->w));
	local_variables.add("image_height", variant(h ? h : image_->h));

	const unsigned x = x_(local_variables);
	VALIDATE_WITH_DEV_MESSAGE(
			  static_cast<int>(x) >= 0
			, _("Image doesn't fit on canvas.")
			, (formatter() << "Image '" << name
				<< "', x = " << static_cast<int>(x) << ".").str());

	const unsigned y = y_(local_variables);
	VALIDATE_WITH_DEV_MESSAGE(
			  static_cast<int>(y) >= 0
			, _("Image doesn't fit on canvas.")
			, (formatter() << "Image '" << name
				<< "', y = " << static_cast<int>(y) << ".").str());

	// Copy the data to local variables to avoid overwriting the originals.
	SDL_Rect src_clip = src_clip_;
	SDL_Rect dst_clip = ::create_rect(x, y, 0, 0);
	surface surf;

	// Test whether we need to scale and do the scaling if needed.
	if(w || h) {
		bool done = false;
		bool stretch_image = (resize_mode_ == stretch) && (!!w ^ !!h);
		if(!w) {
			if(stretch_image) {
				DBG_GUI_D << "Image: vertical stretch from " << image_->w
						<< ',' << image_->h << " to a height of " << h << ".\n";

				surf = stretch_surface_vertical(image_, h, false);
				done = true;
			}
			w = image_->w;
		}

		if(!h) {
			if(stretch_image) {
				DBG_GUI_D << "Image: horizontal stretch from " << image_->w
						<< ',' << image_->h << " to a width of " << w << ".\n";

				surf = stretch_surface_horizontal(image_, w, false);
				done = true;
			}
			h = image_->h;
		}

		if(!done) {

			if(resize_mode_ == tile) {
				DBG_GUI_D << "Image: tiling from " << image_->w
						<< ',' << image_->h << " to " << w << ',' << h << ".\n";

				const int columns = (w + image_->w - 1) / image_->w;
				const int rows = (h + image_->h - 1) / image_->h;
				surf = create_neutral_surface(w, h);

				for(int x = 0; x < columns; ++x) {
					for(int y = 0; y < rows; ++y) {
						const SDL_Rect dest = ::create_rect(
								  x * image_->w
								, y * image_->h
								, 0
								, 0);
						blit_surface(image_, NULL, surf, &dest);
					}
				}

			} else {
				if(resize_mode_ == stretch) {
					ERR_GUI_D << "Image: failed to stretch image, "
							"fall back to scaling.\n";
				}

				DBG_GUI_D << "Image: scaling from " << image_->w
						<< ',' << image_->h << " to " << w << ',' << h << ".\n";

				surf = scale_surface(image_, w, h, false);
			}
		}
		src_clip.w = w;
		src_clip.h = h;
	} else {
		surf = image_;
	}

	if(vertical_mirror_(local_variables)) {
		surf = flip_surface(surf, false);
	}

	blit_surface(surf, &src_clip, canvas, &dst_clip);
}
コード例 #15
0
void tristate_button::draw_contents() {

	surface image(nullptr);

	surface overlay(nullptr);
	surface base = baseImage_;

	int offset = 0;
	switch (state_) {

	case UNINIT:
		return;

	case NORMAL:
		break;

	case TOUCHED_LEFT:
		overlay = touchedUpImage_;
		base = touchedBaseImage_;
		break;
	case TOUCHED_RIGHT:
		overlay = touchedDownImage_;
		base = touchedBaseImage_;
		break;
	case TOUCHED_BOTH_LEFT:
	case TOUCHED_BOTH_RIGHT:
		overlay = touchedBothImage_;
		base = touchedBaseImage_;
		break;
	case ACTIVE:
		//	overlay = activeImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_LEFT:
		base = activeBaseImage_;
		overlay = pressedUpImage_;
		break;
	case PRESSED_RIGHT:
		base = activeBaseImage_;
		overlay = pressedDownImage_;
		break;
	case PRESSED_BOTH:
		base = activeBaseImage_;
		overlay = pressedBothImage_;
		break;
	case PRESSED_ACTIVE_LEFT:
		overlay = pressedUpActiveImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_ACTIVE_BOTH:
		overlay = pressedBothActiveImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_ACTIVE_RIGHT:
		overlay = pressedDownActiveImage_;
		base = activeBaseImage_;
		break;
	}

	image = base;

	const int image_w = image->w;
	const SDL_Rect& loc = location();
	SDL_Rect clipArea = loc;
	const int texty = loc.y + loc.h / 2 - textRect_.h / 2 + offset;
	int textx;

	clipArea.w += image_w + checkbox_horizontal_padding;
	textx = loc.x + image_w + checkbox_horizontal_padding / 2;

	color_t button_color = font::BUTTON_COLOR;

	surface scalled_item;
	scalled_item.assign(scale_surface(itemImage_,
			36, 36));

	surface nitem = make_neutral_surface(scalled_item);
	surface nbase = make_neutral_surface(base);

	//TODO avoid magic numbers
	SDL_Rect r {1, 1, 0, 0};
	sdl_blit(nitem, nullptr, nbase, &r);

	if (!overlay.null()) {
		surface noverlay = make_neutral_surface(overlay);
		sdl_blit(noverlay, nullptr, nbase, nullptr);
	}

	bg_restore();

	image = nbase;
	video().blit_surface(loc.x, loc.y, image);

	clipArea.x += offset;
	clipArea.y += offset;
	clipArea.w -= 2 * offset;
	clipArea.h -= 2 * offset;
	font::draw_text(&video(), clipArea, font_size, button_color, label_, textx,
			texty);
}
コード例 #16
0
surface composer::compose(const std::string &src, const std::string &dest)
{
	cutter cut;
	cut.set_verbose(verbose_);

	const config src_conf = cut.load_config(src);
	const config dest_conf = cut.load_config(dest);

	if(verbose_) {
		std::cerr << "Loading masks...\n";
	}
	cut.load_masks(src_conf);
	cut.load_masks(dest_conf);

	if(verbose_) {
		std::cerr << "Loading images...\n";
	}
	const surface src_surface(make_neutral_surface(IMG_Load(src.c_str())));
	if(src_surface == NULL)
		throw exploder_failure("Unable to load the source image " + src);

	const surface dest_surface(make_neutral_surface(IMG_Load(dest.c_str())));
	if(dest_surface == NULL)
		throw exploder_failure("Unable to load the destination image " + dest);

	if(verbose_) {
		std::cerr << "Cutting images...\n";
	}
	const cutter::surface_map src_surfaces = cut.cut_surface(src_surface, src_conf);
	const cutter::surface_map dest_surfaces = cut.cut_surface(dest_surface, dest_conf);

	for(cutter::surface_map::const_iterator itor = dest_surfaces.begin();
			itor != dest_surfaces.end(); ++itor) {

		const std::string& name = itor->second.name;

		if(src_surfaces.find(name) == src_surfaces.end())
			continue;

		const cutter::positioned_surface& src_ps = src_surfaces.find(name)->second;
		const cutter::positioned_surface& dest_ps = itor->second;

		if(!image_empty(dest_ps.image)) {
			if(interactive_) {
				//TODO: make "interactive" mode work
			} else {
				std::cerr << "Warning: element " << name << " not empty on destination image\n";
			}
		}
		if(verbose_) {
			std::cerr << "Inserting image " << name
				<< " on position (" << dest_ps.pos.x
				<< ", " << dest_ps.pos.y << ")\n";
		}
		masked_overwrite_surface(dest_surface, src_ps.image,
				src_ps.mask.image,
				dest_ps.pos.x, dest_ps.pos.y);
	}

	return dest_surface;
}
コード例 #17
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) << "," << int(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];

				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()) {
					surface tile(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image() + ".png",image::HEXED));

					if(tile == 0) {
						utils::string_map symbols;
						symbols["terrain"] = t_translation::write_terrain_code(terrain);
						const std::string msg =
							vgettext("Could not get image for terrain: $terrain.", symbols);
						VALIDATE(false, msg);
					}

					//Compose images of base and overlay if neccessary
					if(map.get_terrain_info(terrain).is_combined()) {
						surface overlay(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image_overlay() + ".png", image::HEXED));
						if(overlay != 0 && overlay != tile) {
							surface combined = create_compatible_surface(tile, tile->w, tile->h);
							SDL_Rect r;
							r.x = 0;
							r.y = 0;
							SDL_BlitSurface(tile, NULL, combined, &r);
							r.x = std::max(0, (tile->w - overlay->w)/2);
							r.y = std::max(0, (tile->h - overlay->h)/2);
                            if ((overlay->flags & SDL_RLEACCEL) == 0) {
                                blit_surface(overlay, NULL, combined, &r);
                            } else {
                                WRN_DP << map.get_terrain_info(terrain).minimap_image_overlay() << ".png overlay is RLE-encoded, creating a neutral surface\n";
                                surface overlay_neutral = make_neutral_surface(overlay);
							    blit_surface(overlay_neutral, NULL, combined, &r);
                            }
							tile = combined;
						}

					}

					surf = surface(scale_surface_blended(tile,scale,scale));

					VALIDATE(surf != NULL, _("Error creating or aquiring an image."));

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

				surf = i->second;

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

				VALIDATE(surf != NULL, _("Error creating or aquiring an image."));

				// 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 = {x * scale*3/4 - 1,
					y*scale + scale/4 * (is_odd(x) ? 1 : -1) - 1,
					0, 0};
				SDL_BlitSurface(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(minimap,
		static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio));

	DBG_DP << "done generating minimap\n";

	return minimap;
}
コード例 #18
0
ファイル: render.cpp プロジェクト: jorge-barroso/wesnoth
void part_ui::prepare_background()
{
#ifdef SDL_GPU
	base_rect_.w = video_.getx();
	base_rect_.h = video_.gety();
	has_background_ = false;
	bool no_base_yet = true;

	BOOST_FOREACH(const background_layer& bl, p_.get_background_layers()) {
		sdl::timage layer;

		if (!bl.file().empty()) {
			layer = image::get_texture(bl.file());
		}
		has_background_ = has_background_ || !layer.null();
		if(layer.null() || layer.width() * layer.height() == 0) {
			continue;
		}

		const double xscale = 1.0 * video_.getx() / layer.base_width();
		const double yscale = 1.0 * video_.gety() / layer.base_height();
		const bool scalev = bl.scale_vertically();
		const bool scaleh = bl.scale_horizontally();
		const bool keep_ratio = bl.keep_aspect_ratio();
		const bool tileh = bl.tile_horizontally();
		const bool tilev = bl.tile_vertically();

		double x_scale_factor = scaleh ? xscale : 1.0;
		double y_scale_factor = scalev ? yscale : 1.0;

		if (scalev && scaleh && keep_ratio) {
			x_scale_factor = y_scale_factor = std::min<double>(xscale, yscale);
		} else if (keep_ratio && scaleh) {
			x_scale_factor = y_scale_factor = xscale;
		} else if (keep_ratio && scalev) {
			x_scale_factor = y_scale_factor = yscale;
		}

		layer.set_smooth_scaling(true);
		SDL_Rect clip = sdl::create_rect(0, 0, layer.base_width(), layer.base_height());
		if (tileh) {
			clip.x = (layer.base_width() - video_.getx())/2;
			clip.w = video_.getx();
			layer.set_hwrap(GPU_WRAP_REPEAT);
		}
		if (tilev) {
			clip.y = (layer.base_height() - video_.gety())/2;
			clip.h = video_.gety();
			layer.set_vwrap(GPU_WRAP_REPEAT);
		}
		layer.set_clip(clip);
		layer.set_scale(x_scale_factor, y_scale_factor);

		SDL_Rect base_rect = sdl::create_rect(
				  (video_.getx() - layer.width()) / 2
				, (video_.gety() - layer.height()) / 2
				, layer.width()
				, layer.height());

		background_images_.push_back(layer);
		background_positions_.push_back(std::pair<int, int>(base_rect.x, base_rect.y));

		if (bl.is_base_layer() || no_base_yet) {
			x_scale_factor_ = x_scale_factor;
			y_scale_factor_ = y_scale_factor;
			base_rect_ = base_rect;
			no_base_yet = false;
		}
	}
#else
	background_.assign( create_neutral_surface(video_.getx(), video_.gety()) );
	base_rect_.w = video_.getx();
	base_rect_.h = video_.gety();
	has_background_ = false;
	bool no_base_yet = true;

	// Build background surface
	BOOST_FOREACH(const background_layer& bl, p_.get_background_layers()) {
		surface layer;

		if(bl.file().empty() != true) {
			layer.assign( image::get_image(bl.file()) );
		}
		has_background_ = has_background_ || !layer.null();
		if(layer.null() || layer->w * layer->h == 0) {
			continue;
		}

		layer = make_neutral_surface(layer);

		const double xscale = 1.0 * video_.getx() / layer->w;
		const double yscale = 1.0 * video_.gety() / layer->h;
		const bool scalev = bl.scale_vertically();
		const bool scaleh = bl.scale_horizontally();
		const bool keep_ratio = bl.keep_aspect_ratio();

		double x_scale_factor = scaleh ? xscale : 1.0;
		double y_scale_factor = scalev ? yscale : 1.0;

		if (scalev && scaleh && keep_ratio) {
			x_scale_factor = y_scale_factor = std::min<double>(xscale, yscale);
		} else if (keep_ratio && scaleh) {
			x_scale_factor = y_scale_factor = xscale;
		} else if (keep_ratio && scalev) {
			x_scale_factor = y_scale_factor = yscale;
		}

		layer = scale_surface(layer, static_cast<int>(layer->w*x_scale_factor), static_cast<int>(layer->h*y_scale_factor), false);

		const int tilew = bl.tile_horizontally() ? video_.getx() : layer->w;
		const int tileh = bl.tile_vertically() ? video_.gety() : layer->h;

		layer = tile_surface(layer, tilew, tileh, false);

		SDL_Rect drect = sdl::create_rect(
				  (background_->w - layer->w) / 2
				, (background_->h - layer->h) / 2
				, layer->w
				, layer->h);
		SDL_Rect srect = sdl::create_rect(
				  0
				, 0
				, layer->w
				, layer->h);
		SDL_Rect base_rect = drect;

		// If we can't see the whole image anyways, we'll want to display the
		// top-middle area.
		if (drect.y < 0) {
			drect.y = 0;
			base_rect.y = 0;
		}

		if (drect.x < 0) {
			srect.x -= drect.x;
			drect.x = 0;
		}

		blit_surface(layer, &srect, background_, &drect);
		ASSERT_LOG(layer.null() == false, "Oops: a storyscreen part background layer got NULL");

		if (bl.is_base_layer() || no_base_yet) {
			x_scale_factor_ = x_scale_factor;
			y_scale_factor_ = y_scale_factor;
			base_rect_ = base_rect;
			no_base_yet = false;
		}
	}
#endif
}
コード例 #19
0
void tristate_button::draw_contents() {

	surface image(NULL);

	surface overlay(NULL);
	surface base = baseImage_;

	int offset = 0;
	switch (state_) {

	case UNINIT:
		return;

	case NORMAL:
		break;

	case TOUCHED_LEFT:
		overlay = touchedUpImage_;
		base = touchedBaseImage_;
		break;
	case TOUCHED_RIGHT:
		overlay = touchedDownImage_;
		base = touchedBaseImage_;
		break;
	case TOUCHED_BOTH_LEFT:
	case TOUCHED_BOTH_RIGHT:
		overlay = touchedBothImage_;
		base = touchedBaseImage_;
		break;
	case ACTIVE:
		//	overlay = activeImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_LEFT:
		base = activeBaseImage_;
		overlay = pressedUpImage_;
		break;
	case PRESSED_RIGHT:
		base = activeBaseImage_;
		overlay = pressedDownImage_;
		break;
	case PRESSED_BOTH:
		base = activeBaseImage_;
		overlay = pressedBothImage_;
		break;
	case PRESSED_ACTIVE_LEFT:
		overlay = pressedUpActiveImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_ACTIVE_BOTH:
		overlay = pressedBothActiveImage_;
		base = activeBaseImage_;
		break;
	case PRESSED_ACTIVE_RIGHT:
		overlay = pressedDownActiveImage_;
		base = activeBaseImage_;
		break;
	}

	image = base;

	const int image_w = image->w;
	SDL_Rect const &loc = location();
	SDL_Rect clipArea = loc;
	const int texty = loc.y + loc.h / 2 - textRect_.h / 2 + offset;
	int textx;

	clipArea.w += image_w + checkbox_horizontal_padding;
	textx = loc.x + image_w + checkbox_horizontal_padding / 2;

	SDL_Color button_color = font::BUTTON_COLOR;

	surface scalled_item;
	scalled_item.assign(scale_surface(itemImage_,
			36, 36));

	// blit_surface want neutral surfaces
	surface nitem = make_neutral_surface(scalled_item);
	surface nbase = make_neutral_surface(base);

	//TODO avoid magic numbers
	SDL_Rect r = sdl::create_rect(1, 1, 0, 0);
	blit_surface(nitem, NULL, nbase, &r);

	if (!overlay.null()) {
		surface noverlay = make_neutral_surface(overlay);
		blit_surface(noverlay, NULL, nbase, NULL);
	}

//  TODO for later reference
//	SDL_SetAlpha(nbase, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
//	SDL_SetAlpha(image, 0, 0);
//
//	TODO might be needed.
	bg_restore();

	image = nbase;
	video().blit_surface(loc.x, loc.y, image);

	clipArea.x += offset;
	clipArea.y += offset;
	clipArea.w -= 2 * offset;
	clipArea.h -= 2 * offset;
	font::draw_text(&video(), clipArea, font_size, button_color, label_, textx,
			texty);

	update_rect(loc);
}
コード例 #20
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;
}
コード例 #21
0
ファイル: cutter.cpp プロジェクト: Heark/wesnoth
int main(int argc, char* argv[])
{
	std::string src;
	std::string dest_dir;
	cutter cut;

	// Parse arguments that shouldn't require a display device
	int arg;
	for(arg = 1; arg != argc; ++arg) {
		const std::string val(argv[arg]);
		if(val.empty()) {
			continue;
		}

		if(val == "--help" || val == "-h") {
			print_usage(argv[0]);
			return 0;
		} else if(val == "--verbose" || val == "-v") {
			cut.set_verbose(true);
		} else if(val == "--directory" || val == "-d" ) {
			game_config::path = argv[++arg];
		} else {
			if(src.empty()) {
				src = val;
			} else if(dest_dir.empty()) {
				dest_dir = val;
			} else {
				print_usage(argv[0]);
				return 1;
			}
		}
	}

	if(src.empty() || dest_dir.empty()) {
		print_usage(argv[0]);
		return 1;
	}

	try {
		const config conf = cut.load_config(src);
		cut.load_masks(conf);

		const surface src_surface(make_neutral_surface(IMG_Load(src.c_str())));
		if(src_surface == NULL)
			throw exploder_failure("Unable to load the source image " + src);

		const cutter::surface_map surfaces = cut.cut_surface(src_surface, conf);

		for(cutter::surface_map::const_iterator itor = surfaces.begin();
				itor != surfaces.end(); ++itor) {
			const cutter::mask &mask = itor->second.mask;

			surface surf = create_compatible_surface(
					  itor->second.image
					, mask.cut.w
					, mask.cut.h);

			masked_overwrite_surface(surf, itor->second.image, mask.image,
					mask.cut.x - mask.shift.x, mask.cut.y - mask.shift.y);

			save_image(surf, dest_dir + "/" + mask.name + ".png");
		}

	} catch(exploder_failure& err) {
		std::cerr << "Failed: " << err.message << "\n";
		return 1;
	}

	return 0;
}