File diff r19019:2eb1d8782aac → r19020:24d71054fe13
src/spriteloader/grf.cpp
Show inline comments
 
@@ -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::Sp
 
	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(SpriteL
 

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