* Load a real or recolour sprite. * @param load_index Global sprite index. * @param file GRF to load from. * @param file_sprite_id Sprite number in the GRF. * @param container_version Container version of the GRF. * @return True if a valid sprite was loaded, false on any error. */
| 612 | * @return True if a valid sprite was loaded, false on any error. |
| 613 | */ |
| 614 | bool LoadNextSprite(SpriteID load_index, SpriteFile &file, uint file_sprite_id) |
| 615 | { |
| 616 | size_t file_pos = file.GetPos(); |
| 617 | |
| 618 | /* Read sprite header. */ |
| 619 | uint32_t num = file.GetContainerVersion() >= 2 ? file.ReadDword() : file.ReadWord(); |
| 620 | if (num == 0) return false; |
| 621 | uint8_t grf_type = file.ReadByte(); |
| 622 | |
| 623 | SpriteType type; |
| 624 | SpriteCacheCtrlFlags control_flags; |
| 625 | if (grf_type == 0xFF) { |
| 626 | /* Some NewGRF files have "empty" pseudo-sprites which are 1 |
| 627 | * byte long. Catch these so the sprites won't be displayed. */ |
| 628 | if (num == 1) { |
| 629 | file.ReadByte(); |
| 630 | return false; |
| 631 | } |
| 632 | file_pos = file.GetPos(); |
| 633 | type = SpriteType::Recolour; |
| 634 | file.SkipBytes(num); |
| 635 | } else if (file.GetContainerVersion() >= 2 && grf_type == 0xFD) { |
| 636 | if (num != 4) { |
| 637 | /* Invalid sprite section include, ignore. */ |
| 638 | file.SkipBytes(num); |
| 639 | return false; |
| 640 | } |
| 641 | /* It is not an error if no sprite with the provided ID is found in the sprite section. */ |
| 642 | auto iter = _grf_sprite_offsets.find(file.ReadDword()); |
| 643 | if (iter != _grf_sprite_offsets.end()) { |
| 644 | file_pos = iter->second.file_pos; |
| 645 | control_flags = iter->second.control_flags; |
| 646 | } else { |
| 647 | file_pos = SIZE_MAX; |
| 648 | } |
| 649 | type = SpriteType::Normal; |
| 650 | } else { |
| 651 | file.SkipBytes(7); |
| 652 | type = SkipSpriteData(file, grf_type, num - 8) ? SpriteType::Normal : SpriteType::Invalid; |
| 653 | /* Inline sprites are not supported for container version >= 2. */ |
| 654 | if (file.GetContainerVersion() >= 2) return false; |
| 655 | } |
| 656 | |
| 657 | if (type == SpriteType::Invalid) return false; |
| 658 | |
| 659 | if (load_index >= MAX_SPRITES) { |
| 660 | UserError("Tried to load too many sprites (#{}; max {})", load_index, MAX_SPRITES); |
| 661 | } |
| 662 | |
| 663 | bool is_mapgen = IsMapgenSpriteID(load_index); |
| 664 | |
| 665 | if (is_mapgen) { |
| 666 | if (type != SpriteType::Normal) UserError("Uhm, would you be so kind not to load a NewGRF that changes the type of the map generator sprites?"); |
| 667 | type = SpriteType::MapGen; |
| 668 | } |
| 669 | |
| 670 | SpriteCache *sc = AllocateSpriteCache(load_index); |
| 671 | sc->file = &file; |
no test coverage detected