From ee5da71a4f0806e662e4239bdb341c40d5a02970 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 2 May 2025 14:02:56 +0200 Subject: [PATCH] Codechange: Deduplicate array lookup. --- src/blitter/32bpp_optimized.cpp | 9 ++-- src/blitter/32bpp_simple.cpp | 17 ++++--- src/blitter/32bpp_sse2.cpp | 27 +++++----- src/blitter/8bpp_optimized.cpp | 16 +++--- src/blitter/8bpp_simple.cpp | 15 +++--- src/blitter/null.cpp | 9 ++-- src/spritecache.cpp | 88 ++++++++++++++++++--------------- src/spriteloader/grf.cpp | 34 +++++++------ src/video/opengl.cpp | 8 +-- 9 files changed, 123 insertions(+), 100 deletions(-) diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index f6acc3c6d1..d4446375e5 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -417,10 +417,11 @@ Sprite *Blitter_32bppOptimized::EncodeInternal(SpriteType sprite_type, const Spr Sprite *dest_sprite = allocator.Allocate(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)); diff --git a/src/blitter/32bpp_simple.cpp b/src/blitter/32bpp_simple.cpp index 6d210216e2..4a3861a8b2 100644 --- a/src/blitter/32bpp_simple.cpp +++ b/src/blitter/32bpp_simple.cpp @@ -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(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width) * sizeof(*dst)); + Sprite *dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + static_cast(root_sprite.height) * static_cast(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(dest_sprite->data); + SpriteLoader::CommonPixel *src = reinterpret_cast(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; diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 026dbc0627..fec59bc1f9 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -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(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(&dst_sprite->data[sizeof(SpriteData) + info.sprite_offset]); + MapValue *dst_mv = reinterpret_cast(&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(reinterpret_cast(dst_rgba_line) + info.sprite_line_size); /* Count the number of transparent pixels from the right. */ dst_rgba = dst_rgba_line - 1; diff --git a/src/blitter/8bpp_optimized.cpp b/src/blitter/8bpp_optimized.cpp index 46aab4f793..a670b8a4bf 100644 --- a/src/blitter/8bpp_optimized.cpp +++ b/src/blitter/8bpp_optimized.cpp @@ -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(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; diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp index b8a9cce142..9e80909068 100644 --- a/src/blitter/8bpp_simple.cpp +++ b/src/blitter/8bpp_simple.cpp @@ -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(sizeof(*dest_sprite) + static_cast(sprite[ZOOM_LVL_MIN].height) * static_cast(sprite[ZOOM_LVL_MIN].width)); + dest_sprite = allocator.Allocate(sizeof(*dest_sprite) + static_cast(root_sprite.height) * static_cast(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; diff --git a/src/blitter/null.cpp b/src/blitter/null.cpp index 188cdf6e4f..5b3922ea04 100644 --- a/src/blitter/null.cpp +++ b/src/blitter/null.cpp @@ -20,10 +20,11 @@ Sprite *Blitter_Null::Encode(SpriteType, const SpriteLoader::SpriteCollection &s Sprite *dest_sprite; dest_sprite = allocator.Allocate(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; } diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 6bf29e747c..2eec68db0b 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -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(sprite[tgt].width) * sprite[tgt].height); + dest_sprite.AllocateData(tgt, static_cast(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(sprite[zoom].height) * sprite[zoom].width); + dest_sprite.AllocateData(zoom, static_cast(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(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; diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index 053a2120e5..e14d96892c 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -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; diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index f7f8736f4a..a0238a77f4 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -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);