12 uint16_t width, height, bpp;
18 static int read_sprite(struct sprite *spr, int pixsz, FILE *fp);
21 void destroy_sprites(struct sprites *ss)
25 for(i=0; i<ss->num_sprites; i++) {
26 free(ss->sprites[i].ops);
31 int load_sprites(struct sprites *ss, const char *fname)
35 struct file_header hdr;
39 if(!(fp = fopen(fname, "rb"))) {
40 fprintf(stderr, "failed to load sprites from %s: %s\n", fname, strerror(errno));
43 if(fread(&hdr, sizeof hdr, 1, fp) <= 0) {
44 fprintf(stderr, "unexpected EOF while reading from %s\n", fname);
47 if(memcmp(hdr.magic, "RLESPRIT", sizeof hdr.magic) != 0) {
48 fprintf(stderr, "invalid magic in %s\n", fname);
52 ss->width = hdr.width;
53 ss->height = hdr.height;
55 ss->num_sprites = hdr.count;
57 if(!(ss->sprites = malloc(hdr.count * sizeof *ss->sprites))) {
58 fprintf(stderr, "failed to allocate %d sprites for %s\n", hdr.count, fname);
62 for(i=0; i<ss->num_sprites; i++) {
63 if(read_sprite(ss->sprites + i, (hdr.bpp + 7) / 8, fp) == -1) {
77 static int read_sprite(struct sprite *spr, int pixsz, FILE *fp)
79 int i, idx, max_ops, newmax, len, bufsz;
84 spr->num_ops = max_ops = 0;
88 if(fread(&op, sizeof op, 1, fp) <= 0) {
93 /* realloc ops array if necessary */
94 if(spr->num_ops >= max_ops) {
95 newmax = max_ops ? max_ops << 1 : 16;
96 if(!(tmp = realloc(spr->ops, newmax * sizeof *spr->ops))) {
97 fprintf(stderr, "failed to add sprite op (newmax: %d)\n", newmax);
105 idx = spr->num_ops++;
106 spr->ops[idx].op = SOP_OP(op);
109 spr->ops[idx].size = bufsz;
111 /* if the op was copy, we need to grab the pixel data */
112 if(SOP_OP(op) == SOP_COPY) {
113 if(!(tmp = malloc(bufsz))) {
114 fprintf(stderr, "failed to allocate sprite pixel data (%d bytes)\n", bufsz);
117 if(fread(tmp, 1, bufsz, fp) < bufsz) {
118 fprintf(stderr, "unexpected EOF while trying to read sprite data (%d pixels)\n", len);
121 spr->ops[idx].data = tmp;
123 spr->ops[idx].data = 0;
126 } while(SOP_OP(op) != SOP_END);
131 for(i=0; i<spr->num_ops; i++) {
132 free(spr->ops[i].data);