- Sprite *MArtReader::readStaticSprite(unsigned int32 id)
- {
- index->seek(12 * (id + STATIC_OFFSET));
- unsigned int32 offset = index->read_uint32_little();
- data->seek(offset + 4); // 4 to skip some header (size?)
- unsigned int32 width = data->read_uint16_little();
- unsigned int32 height = data->read_uint16_little();
- #ifdef SANE
- if ((width == 0) || (width >= 1024) ||
- (height == 0) || (height >= 1024)) {
- System::panic("MArtReader::readStaticSprite, invalid dimension");
- }
- #endif
- Sprite *sprite = new Sprite(width, height);
- for (unsigned int32 i= 0; i< height; i++) {
- linebuf[i] = data->read_uint16_little();
- }
- unsigned int32 mask_line = (width >> 3) + 1;
- unsigned int32 mask_size = height * mask_line;
- unsigned byte *mask = (unsigned byte *) malloc(mask_size, "Sprite.mask");
- memset(mask, 0, mask_size);
- sprite->mask = mask;
- sprite->stretched = true;
- unsigned int32 dstart = offset + 8 + height * 2;
- unsigned int32 y = 0;
- unsigned int32 x = 0;
- data->seek(dstart + (linebuf[y] << 1));
- unsigned int32 runs = 0;
- while(y < height) {
- unsigned int32 offset = data->read_uint16_little();
- unsigned int32 runby = data->read_uint16_little();
- x += offset;
- if (offset + runby == 0) {
- y++;
- data->seek(dstart + (linebuf[y] << 1));
- x = 0;
- runs = 0;
- continue;
- }
- #ifdef SANE
- if (x + runby > width) {
- System::panic("MArtReader::readStaticSprite, illegal data");
- }
- #endif
- runs++;
- unsigned byte *mp = mask + (x >> 3) + y * mask_line;
- unsigned int8 m = 1 << (x & 0x7);
- byte *dst = ((byte *) sprite->data) + (y * width * 2) + x * 2;
- for (unsigned int32 r = 0; r < runby; r++) {
- *((unsigned int16 *) dst) = (unsigned int16) data->read_uint16_little();
- *mp |= m;
- dst += 2;
- if ((m <<= 1) == 0) {
- m = 0x01;
- mp++;
- }
- }
- x += runby;
- }
- return sprite;
- }