diff options
Diffstat (limited to 'src/gfx.cpp')
-rw-r--r-- | src/gfx.cpp | 56 |
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); |