summaryrefslogtreecommitdiff
path: root/src/gfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gfx.cpp')
-rw-r--r--src/gfx.cpp56
1 files changed, 49 insertions, 7 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 9ccb036d2..ad775803b 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -1059,18 +1059,19 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub,
/**
* The code for setting up the blitter mode and sprite information before finally drawing the sprite.
* @param sprite The sprite to draw.
- * @param x The X location to draw.
- * @param y The Y location to draw.
- * @param mode The settings for the blitter to pass.
- * @param sub Whether to only draw a sub set of the sprite.
- * @param zoom The zoom level at which to draw the sprites.
+ * @param x The X location to draw.
+ * @param y The Y location to draw.
+ * @param mode The settings for the blitter to pass.
+ * @param sub Whether to only draw a sub set of the sprite.
+ * @param zoom The zoom level at which to draw the sprites.
+ * @param dst Optional parameter for a different blitting destination.
* @tparam ZOOM_BASE The factor required to get the sub sprite information into the right size.
* @tparam SCALED_XY Whether the X and Y are scaled or unscaled.
*/
template <int ZOOM_BASE, bool SCALED_XY>
-static void GfxBlitter(const Sprite * const sprite, int x, int y, BlitterMode mode, const SubSprite * const sub, SpriteID sprite_id, ZoomLevel zoom)
+static void GfxBlitter(const Sprite * const sprite, int x, int y, BlitterMode mode, const SubSprite * const sub, SpriteID sprite_id, ZoomLevel zoom, const DrawPixelInfo *dst = nullptr)
{
- const DrawPixelInfo *dpi = _cur_dpi;
+ const DrawPixelInfo *dpi = (dst != nullptr) ? dst : _cur_dpi;
Blitter::BlitterParams bp;
if (SCALED_XY) {
@@ -1185,6 +1186,47 @@ static void GfxBlitter(const Sprite * const sprite, int x, int y, BlitterMode mo
BlitterFactory::GetCurrentBlitter()->Draw(&bp, mode, zoom);
}
+/**
+ * Draws a sprite to a new RGBA buffer (see Colour union) instead of drawing to the screen.
+ *
+ * @param spriteId The sprite to draw.
+ * @return Pixel buffer, or nullptr if an 8bpp blitter is being used.
+ */
+std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId)
+{
+ Blitter *blitter = BlitterFactory::GetCurrentBlitter();
+ if (!blitter->Is32BppSupported()) return nullptr;
+
+ /* Gather information about the sprite to write, reserve memory */
+ const SpriteID real_sprite = GB(spriteId, 0, SPRITE_WIDTH);
+ const Sprite *sprite = GetSprite(real_sprite, ST_NORMAL);
+ std::unique_ptr<uint32[]> result(new uint32[sprite->width * sprite->height]);
+
+ /* Prepare new DrawPixelInfo - Normally this would be the screen but we want to draw to another buffer here.
+ * Normally, pitch would be scaled screen width, but in our case our "screen" is only the sprite width wide. */
+ DrawPixelInfo dpi;
+ dpi.dst_ptr = result.get();
+ dpi.pitch = sprite->width;
+ dpi.left = 0;
+ dpi.top = 0;
+ dpi.width = sprite->width;
+ dpi.height = sprite->height;
+ dpi.zoom = ZOOM_LVL_NORMAL;
+
+ /* Zero out the allocated memory, there may be garbage present. */
+ uint32 *writeHead = (uint32*)result.get();
+ for (int i = 0; i < sprite->width * sprite->height; i++) {
+ writeHead[i] = 0;
+ }
+
+ /* Temporarily disable screen animations while blitting - This prevents 40bpp_anim from writing to the animation buffer. */
+ _screen_disable_anim = true;
+ GfxBlitter<1, false>(sprite, 0, 0, BM_NORMAL, nullptr, real_sprite, ZOOM_LVL_NORMAL, &dpi);
+ _screen_disable_anim = false;
+
+ return result;
+}
+
static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id)
{
GfxBlitter<ZOOM_LVL_BASE, false>(sprite, x, y, mode, sub, sprite_id, _cur_dpi->zoom);