From 27febd474ccfccd8e5dc09014a7ad919575575aa Mon Sep 17 00:00:00 2001 From: truelight Date: Mon, 11 Jun 2007 11:50:49 +0000 Subject: (svn r10092) -Codechange: code-seperated the spriteloader and blitter from the rest of the code -Add: make it possible to pick your own blitter (-b , -h for overview) -Add: added a new optimized 8bpp blitter (default, caches sprites of all zoom-levels) -Add: added a debug 8bpp blitter and a very slow normal 8bpp blitter --- src/spriteloader/grf.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/spriteloader/grf.cpp (limited to 'src/spriteloader/grf.cpp') diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp new file mode 100644 index 000000000..4d412d6ea --- /dev/null +++ b/src/spriteloader/grf.cpp @@ -0,0 +1,96 @@ +#include "../stdafx.h" +#include "../gfx.h" +#include "../fileio.h" +#include "../debug.h" +#include "grf.hpp" + +bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint32 file_pos) +{ + /* Open the right file and go to the correct position */ + FioSeekToFile(file_pos); + + /* Read the size and type */ + int num = FioReadWord(); + byte type = FioReadByte(); + + /* Type 0xFF indicates either a colormap or some other non-sprite info; we do not handle them here */ + if (type == 0xFF) return false; + + sprite->height = FioReadByte(); + sprite->width = FioReadWord(); + sprite->x_offs = FioReadWord(); + sprite->y_offs = FioReadWord(); + + /* 0x02 indicates it is a compressed sprite, so we can't rely on 'num' to be valid. + * In case it is uncompressed, the size is 'num' - 8 (header-size). */ + num = (type & 0x02) ? sprite->width * sprite->height : num - 8; + + /* XXX -- We should use a pre-located memory segment for this, malloc/free is pretty expensive */ + byte *dest_orig = MallocT(num); + byte *dest = dest_orig; + + /* Read the file, which has some kind of compression */ + while (num > 0) { + int8 code = FioReadByte(); + + if (code >= 0) { + /* Plain bytes to read */ + int size = (code == 0) ? 0x80 : code; + num -= size; + for (; size > 0; size--) { + *dest = FioReadByte(); + dest++; + } + } else { + /* Copy bytes from earlier in the sprite */ + const uint data_offset = ((code & 7) << 8) | FioReadByte(); + int size = -(code >> 3); + num -= size; + for (; size > 0; size--) { + *dest = *(dest - data_offset); + dest++; + } + } + } + + assert(num == 0); + + sprite->data = CallocT(sprite->width * sprite->height); + + /* When there are transparency pixels, this format has an other trick.. decode it */ + if (type & 0x08) { + for (int y = 0; y < sprite->height; y++) { + bool last_item = false; + /* Look up in the header-table where the real data is stored for this row */ + int offset = (dest_orig[y * 2 + 1] << 8) | dest_orig[y * 2]; + /* Go to that row */ + dest = &dest_orig[offset]; + + do { + SpriteLoader::CommonPixel *data; + /* Read the header: + * 0 .. 14 - length + * 15 - last_item + * 16 .. 31 - transparency bytes */ + last_item = ((*dest) & 0x80) != 0; + int length = (*dest++) & 0x7F; + int skip = *dest++; + + data = &sprite->data[y * sprite->width + skip]; + + for (int x = 0; x < length; x++) { + data->m = *dest; + dest++; + data++; + } + } while (!last_item); + } + } else { + dest = dest_orig; + for (int i = 0; i < sprite->width * sprite->height; i++) + sprite->data[i].m = dest[i]; + } + + free(dest_orig); + return true; +} -- cgit v1.2.3-70-g09d2