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); } } }
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; }
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); } } }
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); } }
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(); }
/** * 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; }
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; }