File diff r10031:f42fea05eb07 → r10032:66da33ee7ae2
src/spritecache.cpp
Show inline comments
 
@@ -51,82 +51,94 @@ static SpriteCache *AllocateSpriteCache(
 
		DEBUG(sprite, 4, "Increasing sprite cache to %d items (%d bytes)", items, items * sizeof(*_spritecache));
 

	
 
		_spritecache = ReallocT(_spritecache, items);
 

	
 
		/* Reset the new items and update the count */
 
		memset(_spritecache + _spritecache_items, 0, (items - _spritecache_items) * sizeof(*_spritecache));
 
		_spritecache_items = items;
 
	}
 

	
 
	return GetSpriteCache(index);
 
}
 

	
 

	
 
struct MemBlock {
 
	size_t size;
 
	byte data[VARARRAY_SIZE];
 
};
 

	
 
static uint _sprite_lru_counter;
 
static MemBlock *_spritecache_ptr;
 
static int _compact_cache_counter;
 

	
 
static void CompactSpriteCache();
 

	
 
/**
 
 * Skip the given amount of sprite graphics data.
 
 * @param type the type of sprite (compressed etc)
 
 * @param num the amount of sprites to skip
 
 */
 
void SkipSpriteData(byte type, uint16 num)
 
{
 
	if (type & 2) {
 
		FioSkipBytes(num);
 
	} else {
 
		while (num > 0) {
 
			int8 i = FioReadByte();
 
			if (i >= 0) {
 
				i = (i == 0) ? 0x80 : i;
 
				num -= i;
 
				FioSkipBytes(i);
 
			} else {
 
				i = -(i >> 3);
 
				num -= i;
 
				FioReadByte();
 
			}
 
		}
 
	}
 
}
 

	
 
/**
 
 * Read the sprite header data and then skip the real payload.
 
 * @return true if the sprite is a pseudo sprite.
 
 */
 
static bool ReadSpriteHeaderSkipData()
 
{
 
	uint16 num = FioReadWord();
 
	byte type;
 

	
 
	if (num == 0) return false;
 

	
 
	type = FioReadByte();
 
	if (type == 0xFF) {
 
		FioSkipBytes(num);
 
		/* Some NewGRF files have "empty" pseudo-sprites which are 1
 
		 * byte long. Catch these so the sprites won't be displayed. */
 
		return num != 1;
 
	}
 

	
 
	FioSkipBytes(7);
 
	num -= 8;
 
	if (num == 0) return true;
 

	
 
	if (type & 2) {
 
		FioSkipBytes(num);
 
	} else {
 
		while (num > 0) {
 
			int8 i = FioReadByte();
 
			if (i >= 0) {
 
				num -= i;
 
				FioSkipBytes(i);
 
			} else {
 
				i = -(i >> 3);
 
				num -= i;
 
				FioReadByte();
 
			}
 
		}
 
	}
 
	SkipSpriteData(type, num - 8);
 

	
 
	return true;
 
}
 

	
 
/* Check if the given Sprite ID exists */
 
bool SpriteExists(SpriteID id)
 
{
 
	/* Special case for Sprite ID zero -- its position is also 0... */
 
	if (id == 0) return true;
 
	if (id >= _spritecache_items) return false;
 
	return !(GetSpriteCache(id)->file_pos == 0 && GetSpriteCache(id)->file_slot == 0);
 
}
 

	
 
void* AllocSprite(size_t);
 

	
 
static void* ReadSprite(SpriteCache *sc, SpriteID id, bool real_sprite)
 
{
 
	uint8 file_slot = sc->file_slot;
 
	size_t file_pos = sc->file_pos;
 

	
 
	DEBUG(sprite, 9, "Load sprite %d", id);
 

	
 
	if (!SpriteExists(id)) {
 
		DEBUG(sprite, 1, "Tried to load non-existing sprite #%d. Probable cause: Wrong/missing NewGRFs", id);