summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-01-16 16:43:27 +0100
committerMichael Lutz <michi@icosahedron.de>2021-02-22 22:16:07 +0100
commit02e874145792670c46205d28e876b01de4cc2348 (patch)
tree9222ca749d6433baeef18f761d475d9b88564e4e /src
parentf94b2e73e118522c29898a77c2de4bd23451e1c7 (diff)
downloadopenttd-02e874145792670c46205d28e876b01de4cc2348.tar.xz
Codechange: Allow for using a sprite encoder that is not the currently active blitter when loading a sprite.
Diffstat (limited to 'src')
-rw-r--r--src/blitter/base.hpp12
-rw-r--r--src/spritecache.cpp23
-rw-r--r--src/spritecache.h3
-rw-r--r--src/spriteloader/spriteloader.hpp19
4 files changed, 41 insertions, 16 deletions
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.
*/
@@ -75,11 +80,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.
* @param video The destination pointer (video-buffer) to scroll.
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 */