1
0
Fork 0

Codechange: Deduplicate array lookup.

pull/14198/head
frosch 2025-05-02 14:02:56 +02:00 committed by frosch
parent bb767608de
commit 02082a0211
9 changed files with 123 additions and 100 deletions

View File

@ -417,10 +417,11 @@ Sprite *Blitter_32bppOptimized::EncodeInternal(SpriteType sprite_type, const Spr
Sprite *dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + sizeof(SpriteData) + len);
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
dest_sprite->height = root_sprite.height;
dest_sprite->width = root_sprite.width;
dest_sprite->x_offs = root_sprite.x_offs;
dest_sprite->y_offs = root_sprite.y_offs;
SpriteData *dst = (SpriteData *)dest_sprite->data;
memset(dst, 0, sizeof(*dst));

View File

@ -117,18 +117,19 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height
Sprite *Blitter_32bppSimple::Encode(SpriteType, const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator)
{
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
Blitter_32bppSimple::Pixel *dst;
Sprite *dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + static_cast<size_t>(sprite[ZOOM_LVL_MIN].height) * static_cast<size_t>(sprite[ZOOM_LVL_MIN].width) * sizeof(*dst));
Sprite *dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + static_cast<size_t>(root_sprite.height) * static_cast<size_t>(root_sprite.width) * sizeof(*dst));
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = root_sprite.height;
dest_sprite->width = root_sprite.width;
dest_sprite->x_offs = root_sprite.x_offs;
dest_sprite->y_offs = root_sprite.y_offs;
dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data;
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_MIN].data;
dst = reinterpret_cast<Blitter_32bppSimple::Pixel *>(dest_sprite->data);
SpriteLoader::CommonPixel *src = reinterpret_cast<SpriteLoader::CommonPixel *>(root_sprite.data);
for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) {
for (int i = 0; i < root_sprite.height * root_sprite.width; i++) {
if (src->m == 0) {
dst[i].r = src->r;
dst[i].g = src->g;

View File

@ -39,22 +39,24 @@ Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, const SpriteLoader
uint all_sprites_size = 0;
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
const SpriteLoader::Sprite *src_sprite = &sprite[z];
sd.infos[z].sprite_width = src_sprite->width;
sd.infos[z].sprite_offset = all_sprites_size;
sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
auto &info = sd.infos[z];
info.sprite_width = src_sprite->width;
info.sprite_offset = all_sprites_size;
info.sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
const uint rgba_size = sd.infos[z].sprite_line_size * src_sprite->height;
sd.infos[z].mv_offset = all_sprites_size + rgba_size;
const uint rgba_size = info.sprite_line_size * src_sprite->height;
info.mv_offset = all_sprites_size + rgba_size;
const uint mv_size = sizeof(MapValue) * src_sprite->width * src_sprite->height;
all_sprites_size += rgba_size + mv_size;
}
Sprite *dst_sprite = allocator.Allocate<Sprite>(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size);
dst_sprite->height = sprite[ZOOM_LVL_MIN].height;
dst_sprite->width = sprite[ZOOM_LVL_MIN].width;
dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dst_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
dst_sprite->height = root_sprite.height;
dst_sprite->width = root_sprite.width;
dst_sprite->x_offs = root_sprite.x_offs;
dst_sprite->y_offs = root_sprite.y_offs;
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
/* Copy colours and determine flags. */
@ -64,8 +66,9 @@ Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, const SpriteLoader
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
const SpriteLoader::Sprite *src_sprite = &sprite[z];
const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
Colour *dst_rgba_line = (Colour *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].sprite_offset];
MapValue *dst_mv = (MapValue *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].mv_offset];
const auto &info = sd.infos[z];
Colour *dst_rgba_line = reinterpret_cast<Colour *>(&dst_sprite->data[sizeof(SpriteData) + info.sprite_offset]);
MapValue *dst_mv = reinterpret_cast<MapValue *>(&dst_sprite->data[sizeof(SpriteData) + info.mv_offset]);
for (uint y = src_sprite->height; y != 0; y--) {
Colour *dst_rgba = dst_rgba_line + META_LENGTH;
for (uint x = src_sprite->width; x != 0; x--) {
@ -113,7 +116,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, const SpriteLoader
(*dst_rgba_line).data = nb_pix_transp;
Colour *nb_right = dst_rgba_line + 1;
dst_rgba_line = (Colour*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
dst_rgba_line = reinterpret_cast<Colour *>(reinterpret_cast<std::byte *>(dst_rgba_line) + info.sprite_line_size);
/* Count the number of transparent pixels from the right. */
dst_rgba = dst_rgba_line - 1;

View File

@ -153,13 +153,14 @@ Sprite *Blitter_8bppOptimized::Encode(SpriteType sprite_type, const SpriteLoader
/* Make the sprites per zoom-level */
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
const SpriteLoader::Sprite &src_orig = sprite[i];
/* Store the index table */
uint offset = dst - temp_dst->data;
temp_dst->offset[i] = offset;
/* cache values, because compiler can't cache it */
int scaled_height = sprite[i].height;
int scaled_width = sprite[i].width;
int scaled_height = src_orig.height;
int scaled_width = src_orig.width;
for (int y = 0; y < scaled_height; y++) {
uint trans = 0;
@ -168,7 +169,7 @@ Sprite *Blitter_8bppOptimized::Encode(SpriteType sprite_type, const SpriteLoader
uint8_t *count_dst = nullptr;
/* Store the scaled image */
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
const SpriteLoader::CommonPixel *src = &src_orig.data[y * src_orig.width];
for (int x = 0; x < scaled_width; x++) {
uint colour = src++->m;
@ -220,10 +221,11 @@ Sprite *Blitter_8bppOptimized::Encode(SpriteType sprite_type, const SpriteLoader
/* Allocate the exact amount of memory we need */
Sprite *dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + size);
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
dest_sprite->height = root_sprite.height;
dest_sprite->width = root_sprite.width;
dest_sprite->x_offs = root_sprite.x_offs;
dest_sprite->y_offs = root_sprite.y_offs;
memcpy(dest_sprite->data, temp_dst, size);
return dest_sprite;

View File

@ -63,17 +63,18 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
Sprite *Blitter_8bppSimple::Encode(SpriteType, const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator)
{
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
Sprite *dest_sprite;
dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + static_cast<size_t>(sprite[ZOOM_LVL_MIN].height) * static_cast<size_t>(sprite[ZOOM_LVL_MIN].width));
dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite) + static_cast<size_t>(root_sprite.height) * static_cast<size_t>(root_sprite.width));
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = root_sprite.height;
dest_sprite->width = root_sprite.width;
dest_sprite->x_offs = root_sprite.x_offs;
dest_sprite->y_offs = root_sprite.y_offs;
/* Copy over only the 'remap' channel, as that is what we care about in 8bpp */
for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) {
dest_sprite->data[i] = sprite[ZOOM_LVL_MIN].data[i].m;
for (int i = 0; i < root_sprite.height * root_sprite.width; i++) {
dest_sprite->data[i] = root_sprite.data[i].m;
}
return dest_sprite;

View File

@ -20,10 +20,11 @@ Sprite *Blitter_Null::Encode(SpriteType, const SpriteLoader::SpriteCollection &s
Sprite *dest_sprite;
dest_sprite = allocator.Allocate<Sprite>(sizeof(*dest_sprite));
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
dest_sprite->height = root_sprite.height;
dest_sprite->width = root_sprite.width;
dest_sprite->x_offs = root_sprite.x_offs;
dest_sprite->y_offs = root_sprite.y_offs;
return dest_sprite;
}

View File

@ -222,22 +222,24 @@ SpriteID GetMaxSpriteID()
static bool ResizeSpriteIn(SpriteLoader::SpriteCollection &sprite, ZoomLevel src, ZoomLevel tgt)
{
uint8_t scaled_1 = ScaleByZoom(1, (ZoomLevel)(src - tgt));
const auto &src_sprite = sprite[src];
auto &dest_sprite = sprite[tgt];
/* Check for possible memory overflow. */
if (sprite[src].width * scaled_1 > UINT16_MAX || sprite[src].height * scaled_1 > UINT16_MAX) return false;
if (src_sprite.width * scaled_1 > UINT16_MAX || src_sprite.height * scaled_1 > UINT16_MAX) return false;
sprite[tgt].width = sprite[src].width * scaled_1;
sprite[tgt].height = sprite[src].height * scaled_1;
sprite[tgt].x_offs = sprite[src].x_offs * scaled_1;
sprite[tgt].y_offs = sprite[src].y_offs * scaled_1;
sprite[tgt].colours = sprite[src].colours;
dest_sprite.width = src_sprite.width * scaled_1;
dest_sprite.height = src_sprite.height * scaled_1;
dest_sprite.x_offs = src_sprite.x_offs * scaled_1;
dest_sprite.y_offs = src_sprite.y_offs * scaled_1;
dest_sprite.colours = src_sprite.colours;
sprite[tgt].AllocateData(tgt, static_cast<size_t>(sprite[tgt].width) * sprite[tgt].height);
dest_sprite.AllocateData(tgt, static_cast<size_t>(dest_sprite.width) * dest_sprite.height);
SpriteLoader::CommonPixel *dst = sprite[tgt].data;
for (int y = 0; y < sprite[tgt].height; y++) {
const SpriteLoader::CommonPixel *src_ln = &sprite[src].data[y / scaled_1 * sprite[src].width];
for (int x = 0; x < sprite[tgt].width; x++) {
SpriteLoader::CommonPixel *dst = dest_sprite.data;
for (int y = 0; y < dest_sprite.height; y++) {
const SpriteLoader::CommonPixel *src_ln = &src_sprite.data[y / scaled_1 * src_sprite.width];
for (int x = 0; x < dest_sprite.width; x++) {
*dst = src_ln[x / scaled_1];
dst++;
}
@ -248,23 +250,27 @@ static bool ResizeSpriteIn(SpriteLoader::SpriteCollection &sprite, ZoomLevel src
static void ResizeSpriteOut(SpriteLoader::SpriteCollection &sprite, ZoomLevel zoom)
{
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
const auto &src_sprite = sprite[zoom - 1];
auto &dest_sprite = sprite[zoom];
/* Algorithm based on 32bpp_Optimized::ResizeSprite() */
sprite[zoom].width = UnScaleByZoom(sprite[ZOOM_LVL_MIN].width, zoom);
sprite[zoom].height = UnScaleByZoom(sprite[ZOOM_LVL_MIN].height, zoom);
sprite[zoom].x_offs = UnScaleByZoom(sprite[ZOOM_LVL_MIN].x_offs, zoom);
sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_MIN].y_offs, zoom);
sprite[zoom].colours = sprite[ZOOM_LVL_MIN].colours;
dest_sprite.width = UnScaleByZoom(root_sprite.width, zoom);
dest_sprite.height = UnScaleByZoom(root_sprite.height, zoom);
dest_sprite.x_offs = UnScaleByZoom(root_sprite.x_offs, zoom);
dest_sprite.y_offs = UnScaleByZoom(root_sprite.y_offs, zoom);
dest_sprite.colours = root_sprite.colours;
sprite[zoom].AllocateData(zoom, static_cast<size_t>(sprite[zoom].height) * sprite[zoom].width);
dest_sprite.AllocateData(zoom, static_cast<size_t>(dest_sprite.height) * dest_sprite.width);
SpriteLoader::CommonPixel *dst = sprite[zoom].data;
const SpriteLoader::CommonPixel *src = sprite[zoom - 1].data;
[[maybe_unused]] const SpriteLoader::CommonPixel *src_end = src + sprite[zoom - 1].height * sprite[zoom - 1].width;
SpriteLoader::CommonPixel *dst = dest_sprite.data;
const SpriteLoader::CommonPixel *src = src_sprite.data;
[[maybe_unused]] const SpriteLoader::CommonPixel *src_end = src + src_sprite.height * src_sprite.width;
for (uint y = 0; y < sprite[zoom].height; y++) {
const SpriteLoader::CommonPixel *src_ln = src + sprite[zoom - 1].width;
for (uint y = 0; y < dest_sprite.height; y++) {
const SpriteLoader::CommonPixel *src_ln = src + src_sprite.width;
assert(src_ln <= src_end);
for (uint x = 0; x < sprite[zoom].width; x++) {
for (uint x = 0; x < dest_sprite.width; x++) {
assert(src < src_ln);
if (src + 1 != src_ln && (src + 1)->a != 0) {
*dst = *(src + 1);
@ -274,7 +280,7 @@ static void ResizeSpriteOut(SpriteLoader::SpriteCollection &sprite, ZoomLevel zo
dst++;
src += 2;
}
src = src_ln + sprite[zoom - 1].width;
src = src_ln + src_sprite.width;
}
}
@ -359,15 +365,16 @@ static bool PadSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite_av
/* Pad sprites where needed. */
for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) {
if (HasBit(sprite_avail, zoom)) {
auto &cur_sprite = sprite[zoom];
/* Scaling the sprite dimensions in the blitter is done with rounding up,
* so a negative padding here is not an error. */
int pad_left = std::max(0, sprite[zoom].x_offs - UnScaleByZoom(min_xoffs, zoom));
int pad_top = std::max(0, sprite[zoom].y_offs - UnScaleByZoom(min_yoffs, zoom));
int pad_right = std::max(0, UnScaleByZoom(max_width, zoom) - sprite[zoom].width - pad_left);
int pad_bottom = std::max(0, UnScaleByZoom(max_height, zoom) - sprite[zoom].height - pad_top);
int pad_left = std::max(0, cur_sprite.x_offs - UnScaleByZoom(min_xoffs, zoom));
int pad_top = std::max(0, cur_sprite.y_offs - UnScaleByZoom(min_yoffs, zoom));
int pad_right = std::max(0, UnScaleByZoom(max_width, zoom) - cur_sprite.width - pad_left);
int pad_bottom = std::max(0, UnScaleByZoom(max_height, zoom) - cur_sprite.height - pad_top);
if (pad_left > 0 || pad_right > 0 || pad_top > 0 || pad_bottom > 0) {
if (!PadSingleSprite(&sprite[zoom], zoom, pad_left, pad_top, pad_right, pad_bottom)) return false;
if (!PadSingleSprite(&cur_sprite, zoom, pad_left, pad_top, pad_right, pad_bottom)) return false;
}
}
}
@ -393,10 +400,12 @@ static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite
if (HasBit(sprite_avail, zoom)) {
/* Check that size and offsets match the fully zoomed image. */
assert(sprite[zoom].width == UnScaleByZoom(sprite[ZOOM_LVL_MIN].width, zoom));
assert(sprite[zoom].height == UnScaleByZoom(sprite[ZOOM_LVL_MIN].height, zoom));
assert(sprite[zoom].x_offs == UnScaleByZoom(sprite[ZOOM_LVL_MIN].x_offs, zoom));
assert(sprite[zoom].y_offs == UnScaleByZoom(sprite[ZOOM_LVL_MIN].y_offs, zoom));
[[maybe_unused]] const auto &root_sprite = sprite[ZOOM_LVL_MIN];
[[maybe_unused]] const auto &dest_sprite = sprite[zoom];
assert(dest_sprite.width == UnScaleByZoom(root_sprite.width, zoom));
assert(dest_sprite.height == UnScaleByZoom(root_sprite.height, zoom));
assert(dest_sprite.x_offs == UnScaleByZoom(root_sprite.x_offs, zoom));
assert(dest_sprite.y_offs == UnScaleByZoom(root_sprite.y_offs, zoom));
}
/* Zoom level is not available, or unusable, so create it */
@ -507,15 +516,16 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
* Ugly: yes. Other solution: no. Blame the original author or
* something ;) The image should really have been a data-stream
* (so type = 0xFF basically). */
uint num = sprite[ZOOM_LVL_MIN].width * sprite[ZOOM_LVL_MIN].height;
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
uint num = root_sprite.width * root_sprite.height;
Sprite *s = allocator.Allocate<Sprite>(sizeof(*s) + num);
s->width = sprite[ZOOM_LVL_MIN].width;
s->height = sprite[ZOOM_LVL_MIN].height;
s->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
s->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
s->width = root_sprite.width;
s->height = root_sprite.height;
s->x_offs = root_sprite.x_offs;
s->y_offs = root_sprite.y_offs;
SpriteLoader::CommonPixel *src = sprite[ZOOM_LVL_MIN].data;
SpriteLoader::CommonPixel *src = root_sprite.data;
uint8_t *dest = s->data;
while (num-- > 0) {
*dest++ = src->m;

View File

@ -231,23 +231,24 @@ uint8_t LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s
if (type == 0xFF) return 0;
ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? ZOOM_LVL_NORMAL : ZOOM_LVL_MIN;
auto &dest_sprite = sprite[zoom_lvl];
sprite[zoom_lvl].height = file.ReadByte();
sprite[zoom_lvl].width = file.ReadWord();
sprite[zoom_lvl].x_offs = file.ReadWord();
sprite[zoom_lvl].y_offs = file.ReadWord();
sprite[zoom_lvl].colours = SpriteComponent::Palette;
dest_sprite.height = file.ReadByte();
dest_sprite.width = file.ReadWord();
dest_sprite.x_offs = file.ReadWord();
dest_sprite.y_offs = file.ReadWord();
dest_sprite.colours = SpriteComponent::Palette;
if (sprite[zoom_lvl].width > INT16_MAX) {
if (dest_sprite.width > INT16_MAX) {
WarnCorruptSprite(file, file_pos, __LINE__);
return 0;
}
/* 0x02 indicates it is a compressed sprite, so we can't rely on 'num' to be valid.
* In case it is uncompressed, the size is 'num' - 8 (header-size). */
num = (type & 0x02) ? sprite[zoom_lvl].width * sprite[zoom_lvl].height : num - 8;
num = (type & 0x02) ? dest_sprite.width * dest_sprite.height : num - 8;
if (DecodeSingleSprite(&sprite[zoom_lvl], file, file_pos, sprite_type, num, type, zoom_lvl, SpriteComponent::Palette, 1)) {
if (DecodeSingleSprite(&dest_sprite, file, file_pos, sprite_type, num, type, zoom_lvl, SpriteComponent::Palette, 1)) {
SetBit(avail_8bpp, zoom_lvl);
return avail_8bpp;
}
@ -317,12 +318,13 @@ uint8_t LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s
continue;
}
sprite[zoom_lvl].height = file.ReadWord();
sprite[zoom_lvl].width = file.ReadWord();
sprite[zoom_lvl].x_offs = file.ReadWord();
sprite[zoom_lvl].y_offs = file.ReadWord();
auto &dest_sprite = sprite[zoom_lvl];
dest_sprite.height = file.ReadWord();
dest_sprite.width = file.ReadWord();
dest_sprite.x_offs = file.ReadWord();
dest_sprite.y_offs = file.ReadWord();
if (sprite[zoom_lvl].width > INT16_MAX || sprite[zoom_lvl].height > INT16_MAX) {
if (dest_sprite.width > INT16_MAX || dest_sprite.height > INT16_MAX) {
WarnCorruptSprite(file, file_pos, __LINE__);
return 0;
}
@ -333,13 +335,13 @@ uint8_t LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s
if (colour.Test(SpriteComponent::Alpha)) bpp++;
if (colour.Test(SpriteComponent::Palette)) bpp++;
sprite[zoom_lvl].colours = colour;
dest_sprite.colours = colour;
/* For chunked encoding we store the decompressed size in the file,
* otherwise we can calculate it from the image dimensions. */
uint decomp_size = (type & 0x08) ? file.ReadDword() : sprite[zoom_lvl].width * sprite[zoom_lvl].height * bpp;
uint decomp_size = (type & 0x08) ? file.ReadDword() : dest_sprite.width * dest_sprite.height * bpp;
bool valid = DecodeSingleSprite(&sprite[zoom_lvl], file, file_pos, sprite_type, decomp_size, type, zoom_lvl, colour, 2);
bool valid = DecodeSingleSprite(&dest_sprite, file, file_pos, sprite_type, decomp_size, type, zoom_lvl, colour, 2);
if (file.GetPos() != start_pos + num) {
WarnCorruptSprite(file, file_pos, __LINE__);
return 0;

View File

@ -1408,10 +1408,11 @@ OpenGLSprite::OpenGLSprite(SpriteType sprite_type, const SpriteLoader::SpriteCol
_glActiveTexture(GL_TEXTURE0);
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
const auto &root_sprite = sprite[ZOOM_LVL_MIN];
for (int t = TEX_RGBA; t < NUM_TEX; t++) {
/* Sprite component present? */
if (t == TEX_RGBA && sprite[ZOOM_LVL_MIN].colours == SpriteComponent::Palette) continue;
if (t == TEX_REMAP && !sprite[ZOOM_LVL_MIN].colours.Test(SpriteComponent::Palette)) continue;
if (t == TEX_RGBA && root_sprite.colours == SpriteComponent::Palette) continue;
if (t == TEX_REMAP && !root_sprite.colours.Test(SpriteComponent::Palette)) continue;
/* Allocate texture. */
_glGenTextures(1, &this->tex[t]);
@ -1436,7 +1437,8 @@ OpenGLSprite::OpenGLSprite(SpriteType sprite_type, const SpriteLoader::SpriteCol
/* Upload texture data. */
for (int i = 0; i < (sprite_type == SpriteType::Font ? 1 : ZOOM_LVL_END); i++) {
this->Update(sprite[i].width, sprite[i].height, i, sprite[i].data);
const auto &src_sprite = sprite[i];
this->Update(src_sprite.width, src_sprite.height, i, src_sprite.data);
}
assert(_glGetError() == GL_NO_ERROR);