MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / ReadSprite

Function ReadSprite

src/spritecache.cpp:455–534  ·  view source on GitHub ↗

* 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. */

Source from the content-addressed store, hash-verified

453 * @return Read sprite data.
454 */
455static 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

Callers 1

GetRawSpriteFunction · 0.85

Calls 9

IsMapgenSpriteIDFunction · 0.85
GetRawSpriteFunction · 0.85
ResizeSpritesFunction · 0.85
GetContainerVersionMethod · 0.80
NoneMethod · 0.80
AnyMethod · 0.80
Is32BppSupportedMethod · 0.45
LoadSpriteMethod · 0.45
EncodeMethod · 0.45

Tested by

no test coverage detected