X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fimage.c;h=ef2898e25b258478bca80bf61a6f595480931d8e;hb=11db3a75c0ab5b9e8c98b4cdbb17080f9dc3d1a5;hp=9dd4c249ec18004925481adf135f5e78e43cbc45;hpb=da14f69fd95c7bd5a0d70cdf4935af06f1f20a04;p=rocksndiamonds.git diff --git a/src/libgame/image.c b/src/libgame/image.c index 9dd4c249..ef2898e2 100644 --- a/src/libgame/image.c +++ b/src/libgame/image.c @@ -1,43 +1,53 @@ /*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * +* Artsoft Retro-Game Library * *----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * +* (c) 1994-2001 Artsoft Entertainment * +* Holger Schemel * +* Detmolder Strasse 189 * +* 33604 Bielefeld * +* Germany * +* e-mail: info@artsoft.org * *----------------------------------------------------------* -* image.c * +* image.c * ***********************************************************/ -#if defined(TARGET_X11) - #include "image.h" #include "pcx.h" #include "misc.h" + +#if defined(TARGET_X11) + /* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */ Image *newImage(unsigned int width, unsigned int height, unsigned int depth) { Image *image; - const unsigned int bytes_per_pixel = 1; + unsigned int bytes_per_pixel = (depth + 7) / 8; int i; +#if 0 if (depth > 8) Error(ERR_EXIT, "images with more than 256 colors are not supported"); depth = 8; +#endif + image = checked_malloc(sizeof(Image)); image->data = checked_malloc(width * height * bytes_per_pixel); image->width = width; image->height = height; image->depth = depth; + image->bytes_per_pixel = bytes_per_pixel; + image->bytes_per_row = width * bytes_per_pixel; + image->rgb.used = 0; for (i=0; irgb.color_used[i] = FALSE; + image->type = (depth < 8 ? IMAGETYPE_BITMAP : + depth > 8 ? IMAGETYPE_TRUECOLOR : IMAGETYPE_RGB); + return image; } @@ -52,26 +62,39 @@ void freeImage(Image *image) /* extra colors to try allocating in private color maps to minimize flashing */ #define NOFLASH_COLORS 256 -/* architecture independent value-to-memory conversion +/* architecture independent value <-> memory conversions; note: the internal format is big endian */ -#define value_to_memory(value, ptr, length) ( \ -(length) == 1 ? (*( (byte *)(ptr) ) = ( value ) ) : \ -(length) == 2 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+1) = ( value ) ) : \ -(length) == 3 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>>16), \ - *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+2) = ( value ) ) : \ - (*( (byte *)(ptr) ) = (((unsigned long)(value))>>24), \ - *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \ - *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+3) = ( value ) )) +#define memory_to_value(ptr, len) ( \ +(len) == 1 ? (unsigned long)( *( (byte *)(ptr)) ) : \ +(len) == 2 ? (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<< 8) \ + + ( *(((byte *)(ptr))+1) ) : \ +(len) == 3 ? (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<<16) \ + + (((unsigned long)(*(((byte *)(ptr))+1)))<< 8) \ + + ( *(((byte *)(ptr))+2) ) : \ + (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<<24) \ + + (((unsigned long)(*(((byte *)(ptr))+1)))<<16) \ + + (((unsigned long)(*(((byte *)(ptr))+2)))<< 8) \ + + ( *(((byte *)(ptr))+3) ) ) + + +#define value_to_memory(value, ptr, len) ( \ +(len) == 1 ? (*( (byte *)(ptr) ) = ( value ) ) : \ +(len) == 2 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+1) = ( value ) ) : \ +(len) == 3 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>>16), \ + *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+2) = ( value ) ) : \ + (*( (byte *)(ptr) ) = (((unsigned long)(value))>>24), \ + *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \ + *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+3) = ( value ) )) static Pixmap Image_to_Mask(Image *image, Display *display, Window window) { byte *src_ptr, *dst_ptr, *dst_ptr2; unsigned int bytes_per_row; - unsigned int x, y; + unsigned int x, y, i; byte bitmask; byte *mask_data; Pixmap mask_pixmap; @@ -94,8 +117,9 @@ static Pixmap Image_to_Mask(Image *image, Display *display, Window window) for (x=0; xwidth; x++) { - if (*src_ptr++) /* source pixel solid? (pixel index != 0) */ - *dst_ptr2 |= bitmask; /* then write a bit into the image mask */ + for (i=0; ibytes_per_pixel; i++) + if (*src_ptr++) /* source pixel solid? (pixel index != 0) */ + *dst_ptr2 |= bitmask; /* then write a bit into the image mask */ if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */ { @@ -145,12 +169,16 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, static int num_cmap_entries, free_cmap_entries; static boolean private_cmap = FALSE; Pixel *redvalue, *greenvalue, *bluevalue; - unsigned int a, c = 0, x, y, bytes_per_pixel, bits_per_pixel; + unsigned int display_bytes_per_pixel, display_bits_per_pixel; + unsigned int a, c = 0, x, y; XColor xcolor; XImage *ximage; XImageInfo *ximageinfo; byte *src_ptr, *dst_ptr; + if (image->type == IMAGETYPE_TRUECOLOR && depth == 8) + Error(ERR_EXIT, "cannot handle true-color images on 8-bit display"); + if (!global_cmap) { if (visual == DefaultVisual(display, screen)) @@ -242,7 +270,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, /* something completely unexpected happened */ - fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n"); + fprintf(stderr, "Image_to_Pixmap: XAllocColor failed on a TrueColor/Directcolor visual\n"); free(redvalue); free(greenvalue); free(bluevalue); @@ -395,14 +423,14 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, /* create XImage from internal image structure and convert it to Pixmap */ - bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth); - bytes_per_pixel = (bits_per_pixel + 7) / 8; + display_bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth); + display_bytes_per_pixel = (display_bits_per_pixel + 7) / 8; ximage = XCreateImage(display, visual, depth, ZPixmap, 0, NULL, image->width, image->height, - 8, image->width * bytes_per_pixel); + 8, image->width * display_bytes_per_pixel); ximage->data = - checked_malloc(image->width * image->height * bytes_per_pixel); + checked_malloc(image->width * image->height * display_bytes_per_pixel); ximage->byte_order = MSBFirst; src_ptr = image->data; @@ -415,25 +443,56 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, { Pixel pixval; - for (y=0; yheight; y++) /* general case */ + switch (image->type) { - for (x=0; xwidth; x++) + case IMAGETYPE_RGB: + { + for (y=0; yheight; y++) /* general case */ + { + for (x=0; xwidth; x++) + { + pixval = *src_ptr++; + pixval = + redvalue[image->rgb.red[pixval] >> 8] | + greenvalue[image->rgb.green[pixval] >> 8] | + bluevalue[image->rgb.blue[pixval] >> 8]; + value_to_memory(pixval, dst_ptr, display_bytes_per_pixel); + dst_ptr += display_bytes_per_pixel; + } + } + break; + } + + case IMAGETYPE_TRUECOLOR: { - pixval = *src_ptr++; - pixval = - redvalue[image->rgb.red[pixval] >> 8] | - greenvalue[image->rgb.green[pixval] >> 8] | - bluevalue[image->rgb.blue[pixval] >> 8]; - value_to_memory(pixval, dst_ptr, bytes_per_pixel); - dst_ptr += bytes_per_pixel; + for (y=0; yheight; y++) /* general case */ + { + for (x=0; xwidth; x++) + { + pixval = memory_to_value(src_ptr, image->bytes_per_pixel); + pixval = + redvalue[TRUECOLOR_RED(pixval)] | + greenvalue[TRUECOLOR_GREEN(pixval)] | + bluevalue[TRUECOLOR_BLUE(pixval)]; + value_to_memory(pixval, dst_ptr, display_bytes_per_pixel); + src_ptr += image->bytes_per_pixel; + dst_ptr += display_bytes_per_pixel; + } + } + break; } + + default: + Error(ERR_RETURN, "image type not supported"); + Error(ERR_EXIT, "RGB or TrueColor image needed"); + break; } break; } case PseudoColor: { - if (bytes_per_pixel == 1) /* (common) special case */ + if (display_bytes_per_pixel == 1) /* special case */ { for (y=0; yheight; y++) for (x=0; xwidth; x++) @@ -446,8 +505,8 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, for (x=0; xwidth; x++) { value_to_memory(ximageinfo->index[c + *src_ptr++], - dst_ptr, bytes_per_pixel); - dst_ptr += bytes_per_pixel; + dst_ptr, display_bytes_per_pixel); + dst_ptr += display_bytes_per_pixel; } } }