#include #include #include #include #include "engine.h" #include // TODO: even better compression using zlib or something - or vector graphics #define MAX_SPRITES 5000 static struct sprite sprites[MAX_SPRITES]; static int numsprites; struct sprite *get_decompressed_sprite(const unsigned char *spritedata) { for(int i = 0; i < numsprites; i++) { if(sprites[i].original_data_source == spritedata) return &sprites[i]; } struct sprite *s = &sprites[numsprites++]; s->width = *(uint16_t*)(spritedata + 0); s->height = *(uint16_t*)(spritedata + 2); s->original_data_source = spritedata; spritedata += 4; s->pixels = (uint32_t*)malloc(s->width*s->height*4); if(!s->pixels) error(1, 0, "get_decompressed_sprite: memory allocation failed"); for(int channel = 0; channel < 4; channel++) { unsigned char *pixels = (unsigned char*)s->pixels; pixels += channel; unsigned int pixelsleft = s->width * s->height; while(pixelsleft > 0) { unsigned char control = *spritedata++; if(control & 0x80) { control &= 0x7f; if(control > pixelsleft) error(1, 0, "corrupted compressed sprite A %u > %u", (unsigned int)control, (unsigned int)pixelsleft); for(int i = 0; i < control; i++) { *pixels = *spritedata++; pixels += 4; } pixelsleft -= control; } else { uint32_t count; if(control == 0) { count = *(uint32_t*)spritedata; spritedata += 4; } else { count = control; } unsigned char value = *spritedata++; if(count > pixelsleft) error(1, 0, "corrupted compressed sprite B %u > %u", (unsigned int)count, (unsigned int)pixelsleft); for(uint32_t i = 0; i < count; i++) { *pixels = value; pixels += 4; } pixelsleft -= count; } } } return s; }