From 02e874145792670c46205d28e876b01de4cc2348 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 16 Jan 2021 16:43:27 +0100 Subject: Codechange: Allow for using a sprite encoder that is not the currently active blitter when loading a sprite. --- src/blitter/base.hpp | 12 ++++++------ src/spritecache.cpp | 23 ++++++++++++++--------- src/spritecache.h | 3 ++- src/spriteloader/spriteloader.hpp | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 10dfce84b..6b19c290b 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -25,7 +25,7 @@ enum BlitterMode { /** * How all blitters should look like. Extend this class to make your own. */ -class Blitter { +class Blitter : public SpriteEncoder { public: /** Parameters related to blitting. */ struct BlitterParams { @@ -58,6 +58,11 @@ public: */ virtual uint8 GetScreenDepth() = 0; + bool Is32BppSupported() override + { + return this->GetScreenDepth() > 8; + } + /** * Draw an image to the screen, given an amount of params defined above. */ @@ -74,11 +79,6 @@ public: */ virtual void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) = 0; - /** - * Convert a sprite from the loader to our own format. - */ - virtual Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) = 0; - /** * Move the destination pointer the requested amount x and y, keeping in mind * any pitch and bpp of the renderer. diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 3029a0253..e1e7d4839 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -404,10 +404,14 @@ static void *ReadRecolourSprite(uint16 file_slot, uint num) * @param id Sprite number. * @param sprite_type Type of sprite. * @param allocator Allocator function to use. + * @param encoder Sprite encoder to use. * @return Read sprite data. */ -static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_type, AllocatorProc *allocator) +static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_type, AllocatorProc *allocator, SpriteEncoder *encoder) { + /* Use current blitter if no other sprite encoder is given. */ + if (encoder == nullptr) encoder = BlitterFactory::GetCurrentBlitter(); + uint8 file_slot = sc->file_slot; size_t file_pos = sc->file_pos; @@ -422,7 +426,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty sprite[ZOOM_LVL_NORMAL].type = sprite_type; SpriteLoaderGrf sprite_loader(sc->container_ver); - if (sprite_type != ST_MAPGEN && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) { + if (sprite_type != ST_MAPGEN && encoder->Is32BppSupported()) { /* Try for 32bpp sprites first. */ sprite_avail = sprite_loader.LoadSprite(sprite, file_slot, file_pos, sprite_type, true); } @@ -433,7 +437,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty if (sprite_avail == 0) { if (sprite_type == ST_MAPGEN) return nullptr; if (id == SPR_IMG_QUERY) usererror("Okay... something went horribly wrong. I couldn't load the fallback sprite. What should I do?"); - return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator); + return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator, encoder); } if (sprite_type == ST_MAPGEN) { @@ -466,7 +470,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty if (!ResizeSprites(sprite, sprite_avail, file_slot, sc->id)) { if (id == SPR_IMG_QUERY) usererror("Okay... something went horribly wrong. I couldn't resize the fallback sprite. What should I do?"); - return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator); + return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator, encoder); } if (sprite->type == ST_FONT && ZOOM_LVL_FONT != ZOOM_LVL_NORMAL) { @@ -478,7 +482,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty sprite[ZOOM_LVL_NORMAL].data = sprite[ZOOM_LVL_FONT].data; } - return BlitterFactory::GetCurrentBlitter()->Encode(sprite, allocator); + return encoder->Encode(sprite, allocator); } @@ -845,9 +849,10 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S * @param sprite Sprite to read. * @param type Expected sprite type. * @param allocator Allocator function to use. Set to nullptr to use the usual sprite cache. + * @param encoder Sprite encoder to use. Set to nullptr to use the currently active blitter. * @return Sprite raw data */ -void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator) +void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator, SpriteEncoder *encoder) { assert(type != ST_MAPGEN || IsMapgenSpriteID(sprite)); assert(type < ST_INVALID); @@ -863,19 +868,19 @@ void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator) if (sc->type != type) return HandleInvalidSpriteRequest(sprite, type, sc, allocator); - if (allocator == nullptr) { + if (allocator == nullptr && encoder == nullptr) { /* Load sprite into/from spritecache */ /* Update LRU */ sc->lru = ++_sprite_lru_counter; /* Load the sprite, if it is not loaded, yet */ - if (sc->ptr == nullptr) sc->ptr = ReadSprite(sc, sprite, type, AllocSprite); + if (sc->ptr == nullptr) sc->ptr = ReadSprite(sc, sprite, type, AllocSprite, nullptr); return sc->ptr; } else { /* Do not use the spritecache, but a different allocator. */ - return ReadSprite(sc, sprite, type, allocator); + return ReadSprite(sc, sprite, type, allocator, encoder); } } diff --git a/src/spritecache.h b/src/spritecache.h index 1b738a865..80e92a8f4 100644 --- a/src/spritecache.h +++ b/src/spritecache.h @@ -11,6 +11,7 @@ #define SPRITECACHE_H #include "gfx_type.h" +#include "spriteloader/spriteloader.hpp" /** Data structure describing a sprite. */ struct Sprite { @@ -25,7 +26,7 @@ extern uint _sprite_cache_size; typedef void *AllocatorProc(size_t size); -void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator = nullptr); +void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator = nullptr, SpriteEncoder *encoder = nullptr); bool SpriteExists(SpriteID sprite); SpriteType GetSpriteType(SpriteID sprite); diff --git a/src/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index 012263171..5a37abc2d 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.hpp @@ -13,6 +13,9 @@ #include "../core/alloc_type.hpp" #include "../gfx_type.h" +struct Sprite; +typedef void *AllocatorProc(size_t size); + /** Interface for the loader of our sprites. */ class SpriteLoader { public: @@ -64,4 +67,20 @@ public: virtual ~SpriteLoader() { } }; +/** Interface for something that can encode a sprite. */ +class SpriteEncoder { +public: + + virtual ~SpriteEncoder() { } + + /** + * Can the sprite encoder make use of RGBA sprites? + */ + virtual bool Is32BppSupported() = 0; + + /** + * Convert a sprite from the loader to our own format. + */ + virtual Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) = 0; +}; #endif /* SPRITELOADER_HPP */ -- cgit v1.2.3-54-g00ecf