1
0
Fork 0

(svn r2522) Reorganize sprite load and decompression in order to remove a special case from the sprite blitter, which decompressed certain sprites every time when blitting them

release/0.4.5
tron 2005-07-05 19:54:35 +00:00
parent b29556e6b5
commit a06b2fdc44
3 changed files with 36 additions and 74 deletions

32
gfx.c
View File

@ -1376,38 +1376,6 @@ static void GfxMainBlitter(const Sprite* sprite, int x, int y, int mode)
} }
bp.start_x = start_x; bp.start_x = start_x;
if (info&2) {
int totpix = bp.height_org * bp.width_org;
byte *dst = (byte*)alloca(totpix);
const byte *src = bp.sprite_org;
bp.sprite = dst + (bp.sprite - bp.sprite_org);
while (totpix != 0) {
signed char b;
assert(totpix > 0);
b = *src++;
if (b >= 0) {
uint count = b;
uint i;
for (i = 0; i != count; i++) dst[i] = src[i];
dst += count;
src += count;
totpix -= count;
} else {
const byte *tmp = dst - (((b & 7) << 8) | *src++);
uint count = -(b >> 3);
uint i;
for (i = 0; i != count; i++) dst[i] = tmp[i];
dst += count;
totpix -= count;
}
}
}
zf_uncomp[dpi->zoom](&bp); zf_uncomp[dpi->zoom](&bp);
} }
} }

View File

@ -31,7 +31,7 @@ uint16 _custom_sprites_base;
static Sprite _cur_sprite; static Sprite _cur_sprite;
static byte *_sprite_ptr[NUM_SPRITES]; static void* _sprite_ptr[NUM_SPRITES];
static uint16 _sprite_size[NUM_SPRITES]; static uint16 _sprite_size[NUM_SPRITES];
static uint32 _sprite_file_pos[NUM_SPRITES]; static uint32 _sprite_file_pos[NUM_SPRITES];
@ -148,11 +148,14 @@ static void ReadSpriteHeaderSkipData(int num, int load_index)
} }
} }
static void ReadSprite(SpriteID id, void *buffer) static void* AllocSprite(size_t);
static void* ReadSprite(SpriteID id)
{ {
uint num = _sprite_size[id]; uint num = _sprite_size[id];
byte type; byte type;
byte* dest;
DEBUG(spritecache, 9) ("load sprite %d", id);
if (_sprite_file_pos[id] == 0) { if (_sprite_file_pos[id] == 0) {
error( error(
@ -165,43 +168,46 @@ static void ReadSprite(SpriteID id, void *buffer)
FioSeekToFile(_sprite_file_pos[id]); FioSeekToFile(_sprite_file_pos[id]);
type = FioReadByte(); type = FioReadByte();
/* We've decoded special sprites when reading headers. */ if (type == 0xFF) {
if (type != 0xFF) { byte* dest = AllocSprite(num);
/* read sprite hdr */
Sprite* sprite = buffer; _sprite_ptr[id] = dest;
FioReadBlock(dest, num);
return dest;
} else {
uint height = FioReadByte();
uint width = FioReadWord();
Sprite* sprite;
byte* dest;
num = (type & 0x02) ? width * height : num - 8;
sprite = AllocSprite(sizeof(*sprite) + num);
_sprite_ptr[id] = sprite;
sprite->info = type; sprite->info = type;
sprite->height = FioReadByte(); sprite->height = (id != 142) ? height : 10;
if (id == 142) sprite->height = 10; // Compensate for a TTD bug sprite->width = width;
sprite->width = FioReadWord();
sprite->x_offs = FioReadWord(); sprite->x_offs = FioReadWord();
sprite->y_offs = FioReadWord(); sprite->y_offs = FioReadWord();
dest = sprite->data;
num -= 8;
} else {
dest = buffer;
}
if (type & 2) { dest = sprite->data;
for (; num > 0; --num)
*dest++ = FioReadByte();
} else {
while (num > 0) { while (num > 0) {
int8 i = FioReadByte(); int8 i = FioReadByte();
if (i >= 0) { if (i >= 0) {
num -= i; num -= i;
for (; i > 0; --i) for (; i > 0; --i) *dest++ = FioReadByte();
*dest++ = FioReadByte();
} else { } else {
const byte* rel = dest - (((i & 7) << 8) | FioReadByte()); const byte* rel = dest - (((i & 7) << 8) | FioReadByte());
i = -(i >> 3); i = -(i >> 3);
num -= i; num -= i;
for (; i > 0; --i) for (; i > 0; --i) *dest++ = *rel++;
*dest++ = *rel++;
} }
} }
return sprite;
} }
} }
@ -499,7 +505,7 @@ static void CompactSpriteCache(void)
if (s->size & S_FREE_MASK) { if (s->size & S_FREE_MASK) {
MemBlock* next = NextBlock(s); MemBlock* next = NextBlock(s);
MemBlock temp; MemBlock temp;
byte** i; void** i;
// Since free blocks are automatically coalesced, this should hold true. // Since free blocks are automatically coalesced, this should hold true.
assert(!(next->size & S_FREE_MASK)); assert(!(next->size & S_FREE_MASK));
@ -606,14 +612,9 @@ static void DeleteEntryFromSpriteCache(void)
} }
} }
static byte *LoadSpriteToMem(SpriteID sprite) static void* AllocSprite(size_t mem_req)
{ {
size_t mem_req; mem_req += sizeof(MemBlock);
DEBUG(spritecache, 9) ("load sprite %d", sprite);
// Number of needed bytes
mem_req = sizeof(MemBlock) + _sprite_size[sprite];
/* Align this to an uint32 boundary. This also makes sure that the 2 least /* Align this to an uint32 boundary. This also makes sure that the 2 least
* bits are not used, so we could use those for other things. */ * bits are not used, so we could use those for other things. */
@ -638,11 +639,6 @@ static byte *LoadSpriteToMem(SpriteID sprite)
NextBlock(s)->size = (cur_size - mem_req) | S_FREE_MASK; NextBlock(s)->size = (cur_size - mem_req) | S_FREE_MASK;
} }
_sprite_ptr[sprite] = s->data;
ReadSprite(sprite, s->data);
// Return sprite ptr
return s->data; return s->data;
} }
} }
@ -698,7 +694,7 @@ static uint RotateSprite(uint s)
const void *GetRawSprite(SpriteID sprite) const void *GetRawSprite(SpriteID sprite)
{ {
byte *p; void* p;
assert(sprite < NUM_SPRITES); assert(sprite < NUM_SPRITES);
@ -714,10 +710,9 @@ const void *GetRawSprite(SpriteID sprite)
_sprite_lru[sprite] = 0; _sprite_lru[sprite] = 0;
#endif #endif
// Check if the sprite is loaded already?
p = _sprite_ptr[sprite]; p = _sprite_ptr[sprite];
if (p == NULL) // Load the sprite, if it is not loaded, yet
p = LoadSpriteToMem(sprite); // No, need to load it. if (p == NULL) p = ReadSprite(sprite);
return p; return p;
} }

View File

@ -9,7 +9,6 @@ typedef struct Sprite {
int16 y_offs; int16 y_offs;
byte data[VARARRAY_SIZE]; byte data[VARARRAY_SIZE];
} Sprite; } Sprite;
assert_compile(sizeof(Sprite) == 8);
typedef struct { typedef struct {
int xoffs, yoffs; int xoffs, yoffs;