grf.cpp
Go to the documentation of this file.00001
00002
00005 #include "../stdafx.h"
00006 #include "../gfx_func.h"
00007 #include "../fileio.h"
00008 #include "../debug.h"
00009 #include "../core/alloc_func.hpp"
00010 #include "grf.hpp"
00011
00012 bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos)
00013 {
00014
00015 FioSeekToFile(file_slot, file_pos);
00016
00017
00018 int num = FioReadWord();
00019 byte type = FioReadByte();
00020
00021
00022 if (type == 0xFF) return false;
00023
00024 sprite->height = FioReadByte();
00025 sprite->width = FioReadWord();
00026 sprite->x_offs = FioReadWord();
00027 sprite->y_offs = FioReadWord();
00028
00029
00030
00031 num = (type & 0x02) ? sprite->width * sprite->height : num - 8;
00032
00033
00034 byte *dest_orig = MallocT<byte>(num);
00035 byte *dest = dest_orig;
00036
00037
00038 while (num > 0) {
00039 int8 code = FioReadByte();
00040
00041 if (code >= 0) {
00042
00043 int size = (code == 0) ? 0x80 : code;
00044 num -= size;
00045 for (; size > 0; size--) {
00046 *dest = FioReadByte();
00047 dest++;
00048 }
00049 } else {
00050
00051 const uint data_offset = ((code & 7) << 8) | FioReadByte();
00052 int size = -(code >> 3);
00053 num -= size;
00054 for (; size > 0; size--) {
00055 *dest = *(dest - data_offset);
00056 dest++;
00057 }
00058 }
00059 }
00060
00061 assert(num == 0);
00062
00063 sprite->data = CallocT<SpriteLoader::CommonPixel>(sprite->width * sprite->height);
00064
00065
00066 if (type & 0x08) {
00067 for (int y = 0; y < sprite->height; y++) {
00068 bool last_item = false;
00069
00070 int offset = (dest_orig[y * 2 + 1] << 8) | dest_orig[y * 2];
00071
00072 dest = &dest_orig[offset];
00073
00074 do {
00075 SpriteLoader::CommonPixel *data;
00076
00077
00078
00079
00080 last_item = ((*dest) & 0x80) != 0;
00081 int length = (*dest++) & 0x7F;
00082 int skip = *dest++;
00083
00084 data = &sprite->data[y * sprite->width + skip];
00085
00086 for (int x = 0; x < length; x++) {
00087 data->m = *dest;
00088 dest++;
00089 data++;
00090 }
00091 } while (!last_item);
00092 }
00093 } else {
00094 dest = dest_orig;
00095 for (int i = 0; i < sprite->width * sprite->height; i++)
00096 sprite->data[i].m = dest[i];
00097 }
00098
00099
00100 for (int i = 0; i < sprite->width * sprite->height; i++)
00101 if (sprite->data[i].m != 0) sprite->data[i].a = 0xFF;
00102
00103 free(dest_orig);
00104 return true;
00105 }