nuclear@4: #include nuclear@4: #include nuclear@4: #include nuclear@4: #include nuclear@4: #include "image.h" nuclear@4: nuclear@4: #define LOADFAIL(f, m) fprintf(stderr, "failed to load image: %s: %s\n", f, m) nuclear@4: nuclear@4: int load_image(struct image *img, const char *fname) nuclear@4: { nuclear@4: static const char *magic = "TILEIMAG"; nuclear@4: FILE *fp; nuclear@4: char sig[8]; nuclear@4: nuclear@4: if(!(fp = fopen(fname, "rb"))) { nuclear@4: LOADFAIL(fname, strerror(errno)); nuclear@4: return -1; nuclear@4: } nuclear@4: if(fread(sig, sizeof sig, 1, fp) <= 0 || memcmp(sig, magic, 8) != 0) { nuclear@4: LOADFAIL(fname, "corrupted or empty file"); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: if(fread(&img->xsz, 4, 1, fp) <= 0 || fread(&img->ysz, 4, 1, fp) <= 0) { nuclear@4: LOADFAIL(fname, "failed to read file header"); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@4: if(!(img->pixels = malloc(img->xsz * img->ysz))) { nuclear@4: LOADFAIL(fname, "failed to allocate pixel buffer"); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: if(fread(img->pixels, 1, img->xsz * img->ysz, fp) < img->xsz * img->ysz) { nuclear@4: LOADFAIL(fname, "unexpected end of file while reading pixels"); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: fclose(fp); nuclear@4: return 0; nuclear@4: } nuclear@4: nuclear@4: void destroy_image(struct image *img) nuclear@4: { nuclear@4: if(img) { nuclear@4: free(img->pixels); nuclear@4: img->pixels = 0; nuclear@4: } nuclear@4: } nuclear@4: nuclear@4: int load_palette(struct color *col, const char *fname) nuclear@4: { nuclear@4: FILE *fp; nuclear@4: char buf[128]; nuclear@4: int nent = 0; nuclear@4: nuclear@4: if(!(fp = fopen(fname, "r"))) { nuclear@4: fprintf(stderr, "failed to open palette file: %s: %s\n", fname, strerror(errno)); nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@4: while(fgets(buf, sizeof buf, fp)) { nuclear@4: char *endp, *line = buf; nuclear@4: int r, g, b; nuclear@4: nuclear@4: if(!line || !*line) continue; nuclear@4: nuclear@4: if(*line == '#') { /* hex html-like values */ nuclear@4: unsigned int val = strtol(line + 1, &endp, 16); nuclear@4: if(endp == line) { nuclear@4: fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@4: r = (val >> 16) & 0xff; nuclear@4: g = (val >> 8) & 0xff; nuclear@4: b = val & 0xff; nuclear@4: } else { nuclear@4: fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname); nuclear@4: fclose(fp); nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@4: if(nent >= 256) { nuclear@4: fprintf(stderr, "palette file %s contains more than 256 entries ... skipping the rest\n", fname); nuclear@4: break; nuclear@4: } nuclear@4: nuclear@4: col[nent].r = r; nuclear@4: col[nent].g = g; nuclear@4: col[nent].b = b; nuclear@4: nent++; nuclear@4: } nuclear@4: nuclear@4: printf("loaded palette: %s (%d colors)\n", fname, nent); nuclear@4: nuclear@4: fclose(fp); nuclear@4: return nent; nuclear@4: } nuclear@4: nuclear@4: #define MIN(a, b) ((a) < (b) ? (a) : (b)) nuclear@4: #define MAX(a, b) ((a) > (b) ? (a) : (b)) nuclear@4: nuclear@4: void blitkey(struct image *destimg, int dstx, int dsty, struct image *srcimg, int key) nuclear@4: { nuclear@4: int srcx = 0, srcy = 0; nuclear@4: int i, j, width, height; nuclear@4: unsigned char *src, *dst; nuclear@4: nuclear@4: if(dstx < 0) { nuclear@4: srcx += -dstx; nuclear@4: dstx = 0; nuclear@4: } nuclear@4: if(dsty < 0) { nuclear@4: srcy += -dsty; nuclear@4: dsty = 0; nuclear@4: } nuclear@4: nuclear@4: width = MIN(destimg->xsz - dstx, srcimg->xsz - srcx); nuclear@4: height = MIN(destimg->ysz - dsty, srcimg->ysz - srcy); nuclear@4: nuclear@4: if(width <= 0 || height <= 0) return; /* ended up with a zero-area blit */ nuclear@4: nuclear@4: src = srcimg->pixels + srcy * srcimg->xsz + srcx; nuclear@4: dst = destimg->pixels + dsty * destimg->xsz + dstx; nuclear@4: nuclear@4: for(i=0; ixsz; nuclear@4: dst += destimg->xsz; nuclear@4: } nuclear@4: }