mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Deduplicate array lookup.
parent
bb767608de
commit
02082a0211
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue