* Read a sprite from disk. * @param sc Location of sprite. * @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. */
| 453 | * @return Read sprite data. |
| 454 | */ |
| 455 | static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_type, SpriteAllocator &allocator, SpriteEncoder *encoder) |
| 456 | { |
| 457 | /* Use current blitter if no other sprite encoder is given. */ |
| 458 | if (encoder == nullptr) encoder = BlitterFactory::GetCurrentBlitter(); |
| 459 | |
| 460 | SpriteFile &file = *sc->file; |
| 461 | size_t file_pos = sc->file_pos; |
| 462 | |
| 463 | assert(sprite_type != SpriteType::Recolour); |
| 464 | assert(IsMapgenSpriteID(id) == (sprite_type == SpriteType::MapGen)); |
| 465 | assert(sc->type == sprite_type); |
| 466 | |
| 467 | Debug(sprite, 9, "Load sprite {}", id); |
| 468 | |
| 469 | SpriteLoader::SpriteCollection sprite; |
| 470 | ZoomLevels sprite_avail; |
| 471 | ZoomLevels avail_8bpp; |
| 472 | ZoomLevels avail_32bpp; |
| 473 | |
| 474 | SpriteLoaderGrf sprite_loader(file.GetContainerVersion()); |
| 475 | if (sprite_type != SpriteType::MapGen && encoder->Is32BppSupported()) { |
| 476 | /* Try for 32bpp sprites first. */ |
| 477 | sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, true, sc->control_flags, avail_8bpp, avail_32bpp); |
| 478 | } |
| 479 | if (sprite_avail.None()) { |
| 480 | sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, false, sc->control_flags, avail_8bpp, avail_32bpp); |
| 481 | if (sprite_type == SpriteType::Normal && avail_32bpp.Any() && !encoder->Is32BppSupported() && sprite_avail.None()) { |
| 482 | /* No 8bpp available, try converting from 32bpp. */ |
| 483 | SpriteLoaderMakeIndexed make_indexed(sprite_loader); |
| 484 | sprite_avail = make_indexed.LoadSprite(sprite, file, file_pos, sprite_type, true, sc->control_flags, sprite_avail, avail_32bpp); |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | if (sprite_avail.None()) { |
| 489 | if (sprite_type == SpriteType::MapGen) return nullptr; |
| 490 | if (id == SPR_IMG_QUERY) UserError("Okay... something went horribly wrong. I couldn't load the fallback sprite. What should I do?"); |
| 491 | return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, &allocator, encoder); |
| 492 | } |
| 493 | |
| 494 | if (sprite_type == SpriteType::MapGen) { |
| 495 | /* Ugly hack to work around the problem that the old landscape |
| 496 | * generator assumes that those sprites are stored uncompressed in |
| 497 | * the memory, and they are only read directly by the code, never |
| 498 | * send to the blitter. So do not send it to the blitter (which will |
| 499 | * result in a data array in the format the blitter likes most), but |
| 500 | * extract the data directly and store that as sprite. |
| 501 | * Ugly: yes. Other solution: no. Blame the original author or |
| 502 | * something ;) The image should really have been a data-stream |
| 503 | * (so type = 0xFF basically). */ |
| 504 | const auto &root_sprite = sprite.Root(); |
| 505 | uint num = root_sprite.width * root_sprite.height; |
| 506 | |
| 507 | Sprite *s = allocator.Allocate<Sprite>(sizeof(*s) + num); |
| 508 | s->width = root_sprite.width; |
| 509 | s->height = root_sprite.height; |
| 510 | s->x_offs = root_sprite.x_offs; |
| 511 | s->y_offs = root_sprite.y_offs; |
| 512 |
no test coverage detected