(svn r23887) -Feature: [NewGRF] Support for container version 2.

This commit is contained in:
michi_cc
2012-02-04 13:29:04 +00:00
parent a9b6c5cd86
commit 6db39410a1
12 changed files with 323 additions and 33 deletions

View File

@@ -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);
}
}

View File

@@ -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);
};