summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-12-31 01:22:45 +0100
committerMichael Lutz <michi@icosahedron.de>2022-01-01 12:19:30 +0100
commit57b992717b5234fa1878567c8ff8907964f1abde (patch)
treecbb21a103c5810ca49b954240c68a856d307f7e2
parent69c8ed9965e2b2bfd6bc04627ca07f78dbcbe2ba (diff)
downloadopenttd-57b992717b5234fa1878567c8ff8907964f1abde.tar.xz
Codechange: Extend DrawSpriteToRgbaBuffer to work with 8bpp blitters.
-rw-r--r--src/gfx.cpp20
-rw-r--r--src/video/cocoa/cocoa_wnd.mm2
2 files changed, 20 insertions, 2 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index e84cf5813..5e2614bc7 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -1200,7 +1200,7 @@ std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo
if (zoom < _settings_client.gui.zoom_min || zoom > _settings_client.gui.zoom_max) return nullptr;
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
- if (!blitter->Is32BppSupported()) return nullptr;
+ if (blitter->GetScreenDepth() != 8 && blitter->GetScreenDepth() != 32) return nullptr;
/* Gather information about the sprite to write, reserve memory */
const SpriteID real_sprite = GB(spriteId, 0, SPRITE_WIDTH);
@@ -1221,11 +1221,29 @@ std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo
dpi.height = dim.height;
dpi.zoom = zoom;
+ /* If the current blitter is a paletted blitter, we have to render to an extra buffer and resolve the palette later. */
+ std::unique_ptr<byte[]> pal_buffer{};
+ if (blitter->GetScreenDepth() == 8) {
+ pal_buffer.reset(new byte[dim.width * dim.height]);
+ MemSetT(pal_buffer.get(), 0, dim.width * dim.height);
+
+ dpi.dst_ptr = pal_buffer.get();
+ }
+
/* Temporarily disable screen animations while blitting - This prevents 40bpp_anim from writing to the animation buffer. */
Backup<bool> disable_anim(_screen_disable_anim, true, FILE_LINE);
GfxBlitter<1, true>(sprite, 0, 0, BM_NORMAL, nullptr, real_sprite, zoom, &dpi);
disable_anim.Restore();
+ if (blitter->GetScreenDepth() == 8) {
+ /* Resolve palette. */
+ uint32 *dst = result.get();
+ const byte *src = pal_buffer.get();
+ for (size_t i = 0; i < dim.height * dim.width; ++i) {
+ *dst++ = _cur_palette.palette[*src++].data;
+ }
+ }
+
return result;
}
diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm
index 95ac3feb1..1876ee27f 100644
--- a/src/video/cocoa/cocoa_wnd.mm
+++ b/src/video/cocoa/cocoa_wnd.mm
@@ -179,7 +179,7 @@ static NSImage *NSImageFromSprite(SpriteID sprite_id, ZoomLevel zoom)
/* Fetch the sprite and create a new bitmap */
Dimension dim = GetSpriteSize(sprite_id, nullptr, zoom);
std::unique_ptr<uint32[]> buffer = DrawSpriteToRgbaBuffer(sprite_id, zoom);
- if (!buffer) return nullptr; // failed to blit sprite or we're using an 8bpp blitter.
+ if (!buffer) return nullptr; // Failed to blit sprite for some reason.
CFAutoRelease<CGDataProvider> data(CGDataProviderCreateWithData(nullptr, buffer.release(), dim.width * dim.height * 4, &CGDataFreeCallback));
if (!data) return nullptr;