Ejemplo n.º 1
0
void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
{
	const SpriteLoader::CommonPixel *src, *src_line;
	uint32 *dst, *dst_line;

	/* Find where to start reading in the source sprite */
	src_line = (const SpriteLoader::CommonPixel *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
	dst_line = (uint32 *)bp->dst + bp->top * bp->pitch + bp->left;

	for (int y = 0; y < bp->height; y++) {
		dst = dst_line;
		dst_line += bp->pitch;

		src = src_line;
		src_line += bp->sprite_width * ScaleByZoom(1, zoom);

		for (int x = 0; x < bp->width; x++) {
			switch (mode) {
				case BM_COLOUR_REMAP:
					/* In case the m-channel is zero, do not remap this pixel in any way */
					if (src->m == 0) {
						if (src->a != 0) *dst = ComposeColourRGBA(src->r, src->g, src->b, src->a, *dst);
					} else {
						if (bp->remap[src->m] != 0) *dst = ComposeColourPA(this->LookupColourInPalette(bp->remap[src->m]), src->a, *dst);
					}
					break;

				case BM_TRANSPARENT:
					/* TODO -- We make an assumption here that the remap in fact is transparency, not some colour.
					 *  This is never a problem with the code we produce, but newgrfs can make it fail... or at least:
					 *  we produce a result the newgrf maker didn't expect ;) */

					/* Make the current colour a bit more black, so it looks like this image is transparent */
					if (src->a != 0) *dst = MakeTransparent(*dst, 192);
					break;

				default:
					if (src->a != 0) *dst = ComposeColourRGBA(src->r, src->g, src->b, src->a, *dst);
					break;
			}
			dst++;
			src += ScaleByZoom(1, zoom);
		}
	}
}
Ejemplo n.º 2
0
	BuildConfirmationWindow(WindowDesc *desc) : Window(desc)
	{
		this->InitNested(0);

		Point pt;
		const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
		NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_BC_OK);

		pt.x = w->viewport->scrollpos_x + ScaleByZoom(_cursor.pos.x - nvp->current_x / 2, w->viewport->zoom);
		pt.y = w->viewport->scrollpos_y + ScaleByZoom(_cursor.pos.y - nvp->current_y / 4, w->viewport->zoom);

		nvp->InitializeViewport(this, 0, w->viewport->zoom);
		nvp->disp_flags |= ND_SHADE_DIMMED;

		this->viewport->scrollpos_x = pt.x;
		this->viewport->scrollpos_y = pt.y;
		this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
		this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;

		BuildConfirmationWindow::shown = true;
	}
Ejemplo n.º 3
0
void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
{
	const uint8 *src, *src_line;
	uint8 *dst, *dst_line;

	/* Find where to start reading in the source sprite */
	src_line = (const uint8 *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
	dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;

	for (int y = 0; y < bp->height; y++) {
		dst = dst_line;
		dst_line += bp->pitch;

		src = src_line;
		src_line += bp->sprite_width * ScaleByZoom(1, zoom);

		for (int x = 0; x < bp->width; x++) {
			uint colour = 0;

			switch (mode) {
				case BM_COLOUR_REMAP:
				case BM_CRASH_REMAP:
					colour = bp->remap[*src];
					break;

				case BM_TRANSPARENT:
					if (*src != 0) colour = bp->remap[*dst];
					break;

				default:
					colour = *src;
					break;
			}
			if (colour != 0) *dst = colour;
			dst++;
			src += ScaleByZoom(1, zoom);
		}
	}
}
Ejemplo n.º 4
0
void Blitter_8bppDebug::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
{
	const uint8 *src, *src_line;
	uint8 *dst, *dst_line;

	/* Find where to start reading in the source sprite */
	src_line = (const uint8 *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
	dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;

	for (int y = 0; y < bp->height; y++) {
		dst = dst_line;
		dst_line += bp->pitch;

		src = src_line;
		src_line += bp->sprite_width * ScaleByZoom(1, zoom);

		for (int x = 0; x < bp->width; x++) {
			if (*src != 0) *dst = *src;
			dst++;
			src += ScaleByZoom(1, zoom);
		}
		assert(src <= src_line);
	}
}
Ejemplo n.º 5
0
void ResetViewportAfterLoadGame()
{
	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);

	w->viewport->scrollpos_x = _saved_scrollpos_x;
	w->viewport->scrollpos_y = _saved_scrollpos_y;
	w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
	w->viewport->dest_scrollpos_y = _saved_scrollpos_y;

	ViewPort *vp = w->viewport;
	vp->zoom = (ZoomLevel)min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
	vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
	vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);

	/* If zoom_max is ZOOM_LVL_MIN then the setting has not been loaded yet, therefore all levels are allowed. */
	if (_settings_client.gui.zoom_max != ZOOM_LVL_MIN) {
		/* Ensure zoom level is allowed */
		while (vp->zoom < _settings_client.gui.zoom_min) DoZoomInOutWindow(ZOOM_OUT, w);
		while (vp->zoom > _settings_client.gui.zoom_max) DoZoomInOutWindow(ZOOM_IN, w);
	}

	DoZoomInOutWindow(ZOOM_NONE, w); // update button status
	MarkWholeScreenDirty();
}
Ejemplo n.º 6
0
/**
 * Resizes the sprite in a very simple way, takes every n-th pixel and every n-th row
 *
 * @param sprite_src sprite to resize
 * @param zoom resizing scale
 * @return resized sprite
 */
static const SpriteLoader::Sprite *ResizeSprite(const SpriteLoader::Sprite *sprite_src, ZoomLevel zoom)
{
	SpriteLoader::Sprite *sprite = MallocT<SpriteLoader::Sprite>(1);

	if (zoom == ZOOM_LVL_NORMAL) {
		memcpy(sprite, sprite_src, sizeof(*sprite));
		uint size = sprite_src->height * sprite_src->width;
		sprite->data = MallocT<SpriteLoader::CommonPixel>(size);
		memcpy(sprite->data, sprite_src->data, size * sizeof(SpriteLoader::CommonPixel));
		return sprite;
	}

	sprite->height = UnScaleByZoom(sprite_src->height, zoom);
	sprite->width  = UnScaleByZoom(sprite_src->width,  zoom);
	sprite->x_offs = UnScaleByZoom(sprite_src->x_offs, zoom);
	sprite->y_offs = UnScaleByZoom(sprite_src->y_offs, zoom);

	uint size = sprite->height * sprite->width;
	SpriteLoader::CommonPixel *dst = sprite->data = CallocT<SpriteLoader::CommonPixel>(size);

	const SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite_src->data;
	const SpriteLoader::CommonPixel *src_end = src + sprite_src->height * sprite_src->width;

	uint scaled_1 = ScaleByZoom(1, zoom);

	for (uint y = 0; y < sprite->height; y++) {
		if (src >= src_end) src = src_end - sprite_src->width;

		const SpriteLoader::CommonPixel *src_ln = src + sprite_src->width * scaled_1;
		for (uint x = 0; x < sprite->width; x++) {
			if (src >= src_ln) src = src_ln - 1;
			*dst = *src;
			dst++;
			src += scaled_1;
		}

		src = src_ln;
	}

	return sprite;
}
Ejemplo n.º 7
0
Sprite *Blitter_8bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
{
	/* Make memory for all zoom-levels */
	uint memory = sizeof(SpriteData);

	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
		memory += UnScaleByZoom(sprite->height, i) * UnScaleByZoom(sprite->width, i);
	}

	/* We have no idea how much memory we really need, so just guess something */
	memory *= 5;

	/* Don't allocate memory each time, but just keep some
	 * memory around as this function is called quite often
	 * and the memory usage is quite low. */
	static ReusableBuffer<byte> temp_buffer;
	SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
	byte *dst = temp_dst->data;

	/* Make the sprites per zoom-level */
	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
		/* Store the index table */
		uint offset = dst - temp_dst->data;
		temp_dst->offset[i] = offset;

		/* cache values, because compiler can't cache it */
		int scaled_height = UnScaleByZoom(sprite->height, i);
		int scaled_width  = UnScaleByZoom(sprite->width,  i);
		int scaled_1      =   ScaleByZoom(1,              i);

		for (int y = 0; y < scaled_height; y++) {
			uint trans = 0;
			uint pixels = 0;
			uint last_colour = 0;
			byte *count_dst = NULL;

			/* Store the scaled image */
			const SpriteLoader::CommonPixel *src = &sprite->data[ScaleByZoom(y, i) * sprite->width];
			const SpriteLoader::CommonPixel *src_end = &src[sprite->width];

			for (int x = 0; x < scaled_width; x++) {
				uint colour = 0;

				/* Get the colour keeping in mind the zoom-level */
				for (int j = 0; j < scaled_1; j++) {
					if (src->m != 0) colour = src->m;
					/* Because of the scaling it might happen we read outside the buffer. Avoid that. */
					if (++src == src_end) break;
				}

				if (last_colour == 0 || colour == 0 || pixels == 255) {
					if (count_dst != NULL) {
						/* Write how many non-transparent bytes we get */
						*count_dst = pixels;
						pixels = 0;
						count_dst = NULL;
					}
					/* As long as we find transparency bytes, keep counting */
					if (colour == 0) {
						last_colour = 0;
						trans++;
						continue;
					}
					/* No longer transparency, so write the amount of transparent bytes */
					*dst = trans;
					dst++;
					trans = 0;
					/* Reserve a byte for the pixel counter */
					count_dst = dst;
					dst++;
				}
				last_colour = colour;
				pixels++;
				*dst = colour;
				dst++;
			}

			if (count_dst != NULL) *count_dst = pixels;

			/* Write line-ending */
			*dst = 0; dst++;
			*dst = 0; dst++;
		}
	}

	uint size = dst - (byte *)temp_dst;

	/* Safety check, to make sure we guessed the size correctly */
	assert(size < memory);

	/* Allocate the exact amount of memory we need */
	Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size);

	dest_sprite->height = sprite->height;
	dest_sprite->width  = sprite->width;
	dest_sprite->x_offs = sprite->x_offs;
	dest_sprite->y_offs = sprite->y_offs;
	memcpy(dest_sprite->data, temp_dst, size);

	return dest_sprite;
}