diff options
author | michi_cc <michi_cc@openttd.org> | 2012-02-04 13:29:04 +0000 |
---|---|---|
committer | michi_cc <michi_cc@openttd.org> | 2012-02-04 13:29:04 +0000 |
commit | 6db39410a1ea0bc8ece1f33fb7771e47d39cc2b7 (patch) | |
tree | d94bcfca3862721c5e6fccff0ec87b79e757cd24 /src/spriteloader | |
parent | a9b6c5cd86f4f17155695890bfaf2e30404f5921 (diff) | |
download | openttd-6db39410a1ea0bc8ece1f33fb7771e47d39cc2b7.tar.xz |
(svn r23887) -Feature: [NewGRF] Support for container version 2.
Diffstat (limited to 'src/spriteloader')
-rw-r--r-- | src/spriteloader/grf.cpp | 67 | ||||
-rw-r--r-- | src/spriteloader/grf.hpp | 2 |
2 files changed, 68 insertions, 1 deletions
diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index 84ed98b94..673647ba4 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -22,6 +22,15 @@ extern const byte _palmap_w2d[]; +/** The different colour components a sprite can have. */ +enum SpriteColourComponent { + SCC_RGB = 1 << 0, ///< Sprite has RGB. + SCC_ALPHA = 1 << 1, ///< Sprite has alpha. + SCC_PAL = 1 << 2, ///< Sprite has palette data. + SCC_MASK = SCC_RGB | SCC_ALPHA | SCC_PAL, ///< Mask of valid colour bits. +}; +DECLARE_ENUM_AS_BIT_SET(SpriteColourComponent) + /** * We found a corrupted sprite. This means that the sprite itself * contains invalid data or is too small for the given dimensions. @@ -176,7 +185,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t fi return true; } -bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type) +bool LoadSpriteV1(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type) { /* Open the right file and go to the correct position */ FioSeekToFile(file_slot, file_pos); @@ -199,3 +208,59 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, return DecodeSingleSprite(sprite, file_slot, file_pos, sprite_type, num, type); } + +bool LoadSpriteV2(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type) +{ + /* Is the sprite not present/stripped in the GRF? */ + if (file_pos == SIZE_MAX) return false; + + /* Open the right file and go to the correct position */ + FioSeekToFile(file_slot, file_pos); + + uint32 id = FioReadDword(); + + do { + int64 num = FioReadDword(); + size_t start_pos = FioGetPos(); + byte type = FioReadByte(); + + /* Type 0xFF indicates either a colourmap or some other non-sprite info; we do not handle them here. */ + if (type == 0xFF) return false; + + byte colour = type & SCC_MASK; + byte zoom = FioReadByte(); + + if (colour == SCC_PAL && zoom == 0) { + sprite->height = FioReadWord(); + sprite->width = FioReadWord(); + sprite->x_offs = FioReadWord(); + sprite->y_offs = FioReadWord(); + + /* Mask out colour information. */ + type = type & ~SCC_MASK; + + /* 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) ? FioReadDword() : sprite->width * sprite->height; + + bool valid = DecodeSingleSprite(sprite, file_slot, file_pos, sprite_type, decomp_size, type); + if (FioGetPos() != start_pos + num) return WarnCorruptSprite(file_slot, file_pos, __LINE__); + return valid; + } else { + /* Not the wanted zoom level or colour depth, continue searching. */ + FioSkipBytes(num - 2); + } + + } while (FioReadDword() == id); + + return false; +} + +bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type) +{ + if (this->container_ver >= 2) { + return LoadSpriteV2(sprite, file_slot, file_pos, sprite_type); + } else { + return LoadSpriteV1(sprite, file_slot, file_pos, sprite_type); + } +} diff --git a/src/spriteloader/grf.hpp b/src/spriteloader/grf.hpp index be41cfd06..97e51c0a1 100644 --- a/src/spriteloader/grf.hpp +++ b/src/spriteloader/grf.hpp @@ -16,7 +16,9 @@ /** Sprite loader for graphics coming from a (New)GRF. */ class SpriteLoaderGrf : public SpriteLoader { + byte container_ver; public: + SpriteLoaderGrf(byte container_ver) : container_ver(container_ver) {} bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type); }; |