home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-18 | 31.0 KB | 1,038 lines |
- /****************************************************************************
- * *
- * sprite.c *
- * ======== *
- * *
- * Sprite ops for conversion routines *
- * *
- * Recognises RISCOS 3.10 modes: *
- * standard, multi, VGA, SVGA, *
- * new multi (896x352), DEEJ large (1152x424 to 1280x512) *
- * *
- * RISCOS 3 True colour 256 by (2) 24 bit palette entry sprites *
- * RISCOS 3 Deep sprites in 1,2,4,8,15/16,24/32 bit depths *
- * *
- * Also DEEJ Technology sprite formats: *
- * *
- * OLD: *
- * mode 0x200 - 15 bpp, 1x1 eig, 2 byte pixels %gggrrrrr,%0bbbbbgg *
- * mode 0x201 - 15 bpp, 1x2 eig, 2 byte pixels %gggrrrrr,%0bbbbbgg *
- *(modes 0x202 & 0x203 reserved for 16bpp paletted, not yet implemented) *
- * mode 0x300 - 24 bpp, 1x1 eig, 3 byte pixels 0xRR,0xGG,0xBB *
- * mode 0x301 - 24 bpp, 1x2 eig, 3 byte pixels 0xRR,0xGG,0xBB *
- * mode 0x402 - 24 bpp, 1x1 eig, 1 WORD pixels 0x00BBGGRR *
- * mode 0x403 - 24 bpp, 1x2 eig, 1 WORD pixels 0x00BBGGRR *
- * *
- * NEW: *
- * Deep sprite type 8 - 24 bpp, 3 byte pixels 0xRR,0xGG,0xBB *
- * *
- * Version 5.10 (15-Jul-1994) *
- * *
- * (C) 1993/4 DEEJ Technology PLC *
- * *
- ****************************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "io.h"
- #include "sprite.h"
-
- static uint read_pixel_val_1(spr_info_str*, int, int);
- static uint read_pixel_rgb_1(spr_info_str*, int, int);
- static void write_pixel_val_1(spr_info_str*, int, int, uint);
- static void write_pixel_rgb_1(spr_info_str*, int, int, uint);
- static uint read_pixel_val_2(spr_info_str*, int, int);
- static uint read_pixel_rgb_2(spr_info_str*, int, int);
- static void write_pixel_val_2(spr_info_str*, int, int, uint);
- static void write_pixel_rgb_2(spr_info_str*, int, int, uint);
- static uint read_pixel_val_4(spr_info_str*, int, int);
- static uint read_pixel_rgb_4(spr_info_str*, int, int);
- static void write_pixel_val_4(spr_info_str*, int, int, uint);
- static void write_pixel_rgb_4(spr_info_str*, int, int, uint);
- static uint read_pixel_val_8(spr_info_str*, int, int);
- static uint read_pixel_rgb_8(spr_info_str*, int, int);
- static void write_pixel_val_8(spr_info_str*, int, int, uint);
- static void write_pixel_rgb_8(spr_info_str*, int, int, uint);
- static uint read_pixel_val_15(spr_info_str*, int, int);
- static uint read_pixel_rgb_15(spr_info_str*, int, int);
- static void write_pixel_val_15(spr_info_str*, int, int, uint);
- static void write_pixel_rgb_15(spr_info_str*, int, int, uint);
- static uint read_pixel_24_24(spr_info_str*, int, int);
- static void write_pixel_24_24(spr_info_str*, int, int, uint);
- static uint read_pixel_24_32_LE(spr_info_str*, int, int);
- static uint read_pixel_24_32_BE(spr_info_str*, int, int);
- static void write_pixel_24_32_LE(spr_info_str*, int, int, uint);
- static void write_pixel_24_32_BE(spr_info_str*, int, int, uint);
-
- /*
- * global description of spritefile structure for read/write_struct()
- */
-
- int spritefile_descr[] = { 4,4,4, 4,12, 4,4, 4,4, 4,4, 4, -1 };
-
-
- extern void alloc_spr_data(spr_info_str *sinfo)
- {
- if((sinfo->spr_data = (uchar*)malloc(sinfo->line_size*sinfo->Y))==0)
- {
- fprintf(stderr,"Could not allocate memory for sprite buffer\n");
- exit(2);
- }
- }
-
- extern void alloc_spr_line(spr_info_str *sinfo)
- {
- if((sinfo->spr_data = (uchar*)malloc(sinfo->line_size))==0)
- {
- fprintf(stderr,"Could not allocate memory for sprite buffer\n");
- exit(2);
- }
- }
-
- /*
- * fill out spr_info fields
- * depending on mode number
- */
-
- void mode_info(spr_info_str *sinfo, spritefile *sprite)
- {
- int xres,yres,type;
-
- sinfo->mode = sprite->mode;
- sinfo->Xasp = 1;
-
- switch(sprite->mode)
- {
- case 18:
- case 23: /* hi-res mono */
- case 25:
- case 29: sinfo->bpp = 1; sinfo->pix = 1; sinfo->Yasp = 1; break;
- case 0:
- case 37:
- case 108:
- case 112: sinfo->bpp = 1; sinfo->pix = 1; sinfo->Yasp = 2; break;
-
- case 19:
- case 26:
- case 30: sinfo->bpp = 2; sinfo->pix = 2; sinfo->Yasp = 1; break;
- case 8:
- case 38:
- case 109:
- case 113: sinfo->bpp = 2; sinfo->pix = 2; sinfo->Yasp = 2; break;
-
- case 20:
- case 27:
- case 31: sinfo->bpp = 4; sinfo->pix = 4; sinfo->Yasp = 1; break;
- case 12:
- case 39:
- case 110:
- case 114: sinfo->bpp = 4; sinfo->pix = 4; sinfo->Yasp = 2; break;
-
- case 21:
- case 28:
- case 32: sinfo->bpp = 8; sinfo->pix = 8; sinfo->Yasp = 1; break;
- case 15:
- case 40:
- case 111:
- case 115: sinfo->bpp = 8; sinfo->pix = 8; sinfo->Yasp = 2; break;
- case 13: sinfo->bpp = 8; sinfo->pix = 8; sinfo->Yasp = 2;
- sinfo->Xasp = 2; break;
-
- /* old extended mode numbers */
-
- /* 8 bit extended format, retained for compatablity with old lib */
- case 0x100:
- case 0x102: sinfo->bpp = 8; sinfo->pix = 8; sinfo->Yasp = 1; break;
- case 0x101:
- case 0x103: sinfo->bpp = 8; sinfo->pix = 8; sinfo->Yasp = 2; break;
-
- /* 15 bpp 16 bit units */
- case 0x200: sinfo->bpp = 15; sinfo->pix = 16; sinfo->Yasp = 1; break;
- case 0x201: sinfo->bpp = 15; sinfo->pix = 16; sinfo->Yasp = 2; break;
-
- /* 24 bpp */
- case 0x300: sinfo->bpp = 24; sinfo->pix = 24; sinfo->Yasp = 1; break;
- case 0x301: sinfo->bpp = 24; sinfo->pix = 24; sinfo->Yasp = 2; break;
-
- /* 24 bpp 32 bit units */
- case 0x400: sinfo->bpp = 24; sinfo->pix = 32; sinfo->Yasp = 1; break;
- case 0x401: sinfo->bpp = 24; sinfo->pix = 32; sinfo->Yasp = 2; break;
-
- default:
- /* check for new deep sprite format */
-
- type = (unsigned)sinfo->mode >> 27;
- xres = (sinfo->mode >> 1) & 0xFFF;
- yres = (sinfo->mode >> 14) & 0xFFF;
-
- if(type != 0)
- {
- switch(type)
- {
- case 1: sinfo->bpp = 1; sinfo->pix = 1; break;
- case 2: sinfo->bpp = 2; sinfo->pix = 2; break;
- case 3: sinfo->bpp = 4; sinfo->pix = 4; break;
- case 4: sinfo->bpp = 8; sinfo->pix = 8; break;
- case 5: sinfo->bpp = 15; sinfo->pix = 16; break;
- case 6: sinfo->bpp = 24; sinfo->pix = 32; break;
- /* case 7: 32 bit CMYK not supported */
- case 8: sinfo->bpp = 24; sinfo->pix = 24; break;
- /* ^^^^^^ DEEJ extension to deep sprite format */
- default:
- fprintf(stderr,"Unsupported mode type %d\n",
- type);
- exit(2);
- }
- sinfo->Xasp = xres==45 ? 2:1;
- sinfo->Yasp = yres==45 ? 2:1;
- }
- else
- {
- fprintf(stderr,"Unrecognised mode %d\n",sinfo->mode);
- exit(2);
- }
- break;
- }
-
- sinfo->cols = 1<<sinfo->bpp;
- sinfo->line_size = (sprite->width+1)*4;
- sinfo->X = (sprite->width*32 +(sprite->right-sprite->left)+1) /
- sinfo->pix;
- sinfo->Y = sprite->height + 1;
-
- /* setup best pixel reading and writing functions */
-
- spr_init_funcs(sinfo);
- }
-
- /*
- * fills in rest of spr_info_structure
- * from pix,bpp,X,Y,Yasp fields
- * choses appropriate mode from bpp & pix
- */
-
- void fill_info(spr_info_str *sinfo)
- {
- int type,xres,yres;
-
- type = 0;
-
- switch(sinfo->bpp)
- {
- case 1:
- if(sinfo->Yasp==1) sinfo->mode = 18;
- else sinfo->mode = 0;
- sinfo->pix = sinfo->bpp;
- break;
-
- case 2:
- if(sinfo->Yasp==1) sinfo->mode = 19;
- else sinfo->mode = 8;
- sinfo->pix = sinfo->bpp;
- break;
-
- case 4:
- if(sinfo->Yasp==1) sinfo->mode = 20;
- else sinfo->mode = 12;
- sinfo->pix = sinfo->bpp;
- break;
-
- case 8:
- if(sinfo->Yasp==1) sinfo->mode = 21;
- else sinfo->mode = 15;
- sinfo->pix = sinfo->bpp;
- break;
-
- case 15:
- type = 5;
- xres = 90;
- if(sinfo->Yasp!=1) yres = 45;
- else yres = 90;
- sinfo->pix = 16;
- break;
-
- case 24:
- if(sinfo->pix == 24)
- {
- /* DEEJ extension to deep sprite format */
- type = 8;
- xres = 90;
- if(sinfo->Yasp!=1) yres = 45;
- else yres = 90;
- sinfo->pix = 24;
- }
- else
- {
- type = 6;
- xres = 90;
- if(sinfo->Yasp!=1) yres = 45;
- else yres = 90;
- sinfo->pix = 32;
- }
- break;
-
- default:
- break;
- }
-
- /* make mode number for deep sprite type */
-
- if(type != 0)
- {
- sinfo->mode = ((unsigned)type << 27) |
- (xres << 1) |
- (yres << 14) | 1;
- }
-
- sinfo->Xasp = 1;
- sinfo->cols = 1<<sinfo->bpp;
- sinfo->line_size = (((sinfo->X*sinfo->pix)+31)/32)*4;
- sinfo->has_palette = (sinfo->bpp<=8) ? sinfo->cols : 0;
-
- /* setup best pixel reading and writing functions */
-
- spr_init_funcs(sinfo);
- }
-
- /*
- * makes a standard 256 colour palette
- */
-
- void palette256(uint *palette)
- {
- int i;
- uint t,r,g,b;
-
- for(i=0; i<256; i++)
- {
- t = i & 3;
- r = ((i>>1) & 8) | (i & 4) | t;
- g = ((i>>3) & 12) | t;
- b = ((i>>4) & 8) | ((i>>1) & 4) | t;
- palette[i] = ((r*0x11)<<8) + ((g*0x11)<<16) + ((b*0x11)<<24);
- }
- }
-
- /*
- * Reads palette for all standard sprites
- * and new 8 & 15 bpp modes
- */
-
- void read_palette(spr_info_str *sinfo, int size, FILE *infile)
- {
- int i;
- uint words[2];
-
- if(size>0)
- {
- for(i=0; i<size/8; i++)
- {
- /* read flash 1/2 pair 0xBBGGRR00 (LE) */
- fread(words, 8, 1, infile);
- /*
- if(words[0] != words[1])
- sprintf(stderr,
- "Warining: palette entry %d is flashing\n",i);
- */
- sinfo->palette[i] = endian(LE,words[0]);
- }
- sinfo->has_palette = size/8;
-
- /* account for 256 colour sprites with old format palette */
-
- if(sinfo->cols==256 && ((size/8)==16 || (size/8)==64))
- {
- default_palette(sinfo);
- }
- }
- else
- {
- /* no palette data in file - make default palettes for mode */
-
- default_palette(sinfo);
- }
- }
-
- /*
- * makes default palettes for all modes
- */
-
- void default_palette(spr_info_str *sinfo)
- {
- int i;
-
- switch(sinfo->bpp)
- {
- case 1:
- sinfo->palette[0] = 0x00000000;
- sinfo->palette[1] = 0xFFFFFF00;
- sinfo->has_palette = 2;
- break;
-
- case 2:
- sinfo->palette[0] = 0x00000000;
- sinfo->palette[1] = 0x0000FF00;
- sinfo->palette[2] = 0x00FFFF00;
- sinfo->palette[3] = 0xFFFFFF00;
- sinfo->has_palette = 4;
- break;
-
- case 4:
- sinfo->palette[0] = 0x00000000;
- sinfo->palette[1] = 0x0000FF00;
- sinfo->palette[2] = 0x00FF0000;
- sinfo->palette[3] = 0x00FFFF00;
- sinfo->palette[4] = 0xFF000000;
- sinfo->palette[5] = 0xFF00FF00;
- sinfo->palette[6] = 0xFFFF0000;
- sinfo->palette[7] = 0xFFFFFF00;
- sinfo->has_palette = 8;
-
- /* substitute for flashing colours of default palette */
- for(i=0; i<8; i++)
- sinfo->palette[i+8] = sinfo->palette[i];
- break;
-
- case 8:
- palette256(sinfo->palette);
- sinfo->has_palette = 256;
- break;
-
- default:
- /* >8 bpp modes have value derived palettes */
- sinfo->has_palette = FALSE;
- break;
- }
- }
-
- /*
- * read sprite from input source
- * fill in spr_info structure
- * assigning approriate palette to output
- */
-
- void read_sprite_header(spr_info_str *in, FILE *infile)
- {
- spritefile sprite;
-
- /* read sprite file header to 'sprite' */
-
- read_struct(LE, (BYTE*)&sprite, spritefile_descr, infile);
-
- if(sprite.offset != 16)
- {
- fprintf(stderr,"Error: bad sprite header offset (corrupt or not a sprite?)\n");
- exit(1);
- }
- if(sprite.number != 1)
- fprintf(stderr,"Warning: more than one sprite in file\n");
- if(sprite.left != 0)
- fprintf(stderr,"Warning: left wastage no longer supported\n");
-
- /* get mode dependant info from sprite */
-
- mode_info(in, &sprite);
- read_palette(in, sprite.sprite-44, infile);
-
- /* read_palette should leave us at sprite data */
- }
-
- /*
- * read sprite header, allocate memory and read sprite data
- */
-
- void read_sprite(spr_info_str *in, FILE *infile)
- {
- read_sprite_header(in, infile);
-
- alloc_spr_data(in);
-
- fread(in->spr_data, in->line_size, in->Y, infile);
- }
-
- /*
- * write sprite header to file
- * using info structure
- */
-
- void write_sprite_header(spr_info_str *out, FILE *outfile)
- {
- int i, pal_size, spr_size;
- uint words[2];
- spritefile sprite;
-
- if(out->bpp > 8)
- pal_size = 0;
- else
- pal_size = out->cols*8;
-
- spr_size = out->line_size * out->Y;
-
- sprite.number = 1;
- sprite.offset = 16;
- sprite.free = spr_size + pal_size + 44 + sprite.offset;
- sprite.next = spr_size + pal_size + 44;
- sprite.width = out->line_size/4 -1;
- sprite.height = out->Y-1;
- sprite.left = 0;
- sprite.right = 31 - (out->line_size*8 - out->X*out->pix);
- sprite.sprite = pal_size + 44;
- sprite.mask = sprite.sprite;
- sprite.mode = out->mode;
-
- memset(sprite.name, 0, 12);
-
- switch(out->pix)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 15:
- case 24:
- sprintf(sprite.name,"sprite%dbpp",out->bpp);
- break;
- case 32:
- sprintf(sprite.name,"sprite24/32");
- break;
- default:
- break;
- }
-
- /* write header to file */
-
- write_struct(LE, (BYTE*)&sprite, spritefile_descr, outfile);
-
- /* write palette */
-
- if(pal_size > 0)
- {
- for(i=0; i<out->cols; i++)
- {
- words[0] = endian(LE,out->palette[i]);
- words[1] = words[0];
- fwrite((char*)words, 8, 1, outfile);
- }
- }
- /* sprite data can now be written to file */
- }
-
- void write_sprite(spr_info_str *out, FILE *outfile)
- {
- write_sprite_header(out, outfile);
- fwrite(out->spr_data, out->line_size, out->Y, outfile);
- }
-
- /*
- * general purpose
- * read 0xBBGGRR00 palette word
- * for sprite pixel x,y
- */
-
- uint read_pixel_RGB(spr_info_str *s, int x, int y)
- {
- uint x0,x1,ppb;
- uint value, r,g,b;
-
- switch(s->bpp)
- {
- case 8:
- value = s->spr_data[s->line_size*y + x];
- break;
-
- case 1:
- case 2:
- case 4:
- ppb = 8/s->pix;
- x0 = x / ppb;
- x1 = (x % ppb)*s->bpp;
- value = s->spr_data[s->line_size*y + x0];
- value = (value >> x1) & (s->cols-1);
- break;
-
- case 15:
- value = s->spr_data[s->line_size*y + x*2 + 0] +
- (s->spr_data[s->line_size*y + x*2 + 1] << 8);
-
- /* extract 5 bit colour fields from index */
-
- r = (value >> 0) & 0x1F;
- g = (value >> 5) & 0x1F;
- b = (value >> 10) & 0x1F;
-
- /* convert 5 bit to 8 bit using */
- /* upper 3 bits for lower 3 bits */
-
- r = (r << 3) | (r >> 2);
- g = (g << 3) | (g >> 2);
- b = (b << 3) | (b >> 2);
-
- return( (b<<24) | (g<<16) | (r<<8) );
- break;
-
- case 24:
- if(s->pix==24)
- {
- value = (s->spr_data[s->line_size*y + x*3 + 0] << 8) |
- (s->spr_data[s->line_size*y + x*3 + 1] << 16) |
- (s->spr_data[s->line_size*y + x*3 + 2] << 24);
- }
- else
- {
- value=endian(LE,*((int*)&s->spr_data[s->line_size*y+x*4]));
-
- /* xxBBGGRR to BBGGRRxx */
- value = (value << 8) | (value >> 24);
- }
- return(value);
- break;
-
- default:
- break;
- }
-
- /* left with paletted modes, so do lookup */
-
- return(s->palette[value]);
- }
-
- /*
- * general purpose
- * read actual data
- * for sprite pixel x,y
- */
-
- uint read_pixel_val(spr_info_str *s, int x, int y)
- {
- int x0,x1,ppb;
- uint value;
-
- switch(s->bpp)
- {
- case 8:
- value = s->spr_data[s->line_size*y + x];
- break;
-
- case 1:
- case 2:
- case 4:
- ppb = 8/s->pix;
- x0 = x / ppb;
- x1 = (x % ppb)*s->bpp;
- value = s->spr_data[s->line_size*y + x0];
- value = (value >> x1) & (s->cols-1);
- break;
-
- case 15:
- value = s->spr_data[s->line_size*y + x*2 + 0] +
- (s->spr_data[s->line_size*y + x*2 + 1] << 8);
- break;
-
- case 24:
- if(s->pix==24)
- {
- value = (s->spr_data[s->line_size*y + x*3 + 0] << 8) |
- (s->spr_data[s->line_size*y + x*3 + 1] << 16) |
- (s->spr_data[s->line_size*y + x*3 + 2] << 24);
- }
- else
- {
- value=endian(LE,*((int*)&s->spr_data[s->line_size*y+x*4]));
-
- /* xxBBGGRR to BBGGRRxx */
- value = (value << 8) | (value >> 24);
- }
- break;
-
- default:
- break;
- }
-
- return(value);
- }
-
- /*
- * general purpose
- * write actual pixel data
- * for sprite pixel x,y
- */
-
- void write_pixel_val(spr_info_str *s, int x, int y, uint value)
- {
- int x0,x1,ppb;
- uint oldval;
-
- switch(s->bpp)
- {
- case 8:
- s->spr_data[s->line_size*y + x] = value;
- break;
-
- case 1:
- case 2:
- case 4:
- ppb = 8/s->pix;
- x0 = x / ppb;
- x1 = (x % ppb)*s->bpp;
- oldval = s->spr_data[s->line_size*y + x0];
- value = (value << x1) | (oldval & ~((s->cols-1) << x1));
- s->spr_data[s->line_size*y + x0] = value;
- break;
-
- case 15:
- s->spr_data[s->line_size*y + x*2 + 0] = value;
- s->spr_data[s->line_size*y + x*2 + 1] = value >> 8;
- break;
-
- case 24:
- if(s->pix==24)
- {
- s->spr_data[s->line_size*y + x*3 + 0] = value >> 8;
- s->spr_data[s->line_size*y + x*3 + 1] = value >> 16;
- s->spr_data[s->line_size*y + x*3 + 2] = value >> 24;
- }
- else
- {
- /* BBGGRRxx to xxBBGGRR */
- value = (value >> 8) | (value << 24);
-
- *((uint*)&s->spr_data[s->line_size*y + x*4]) =
- endian(LE,value);
- }
- break;
-
- default:
- break;
- }
- }
-
- static uint read_pixel_val_1(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>3;
- uint x1 = (x - (x0<<3))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return((value >> x1) & (s->cols-1));
- }
-
- static uint read_pixel_rgb_1(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>3;
- uint x1 = (x - (x0<<3))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return(s->palette[(value >> x1) & (s->cols-1)]);
- }
-
- static void write_pixel_val_1(spr_info_str *s, int x, int y, uint value)
- {
- uint x0 = x>>3;
- uint x1 = (x - (x0<<3))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- value = (value << x1) | (oldval & ~((s->cols-1) << x1));
- s->spr_data[off] = value;
- }
-
- static void write_pixel_rgb_1(spr_info_str *s, int x, int y, uint value)
- {
- pix_str pix;
- uint x0 = x>>3;
- uint x1 = (x - (x0<<3))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- pix.red = (value >> 8) & 0xFF;
- pix.green = (value >> 16) & 0xFF;
- pix.blue = (value >> 24) & 0xFF;
- s->spr_data[off] = (s->closest_rgb(s, &pix)->value << x1)
- | (oldval & ~((s->cols-1) << x1));
- }
-
- static uint read_pixel_val_2(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>2;
- uint x1 = (x - (x0<<2))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return((value >> x1) & (s->cols-1));
- }
-
- static uint read_pixel_rgb_2(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>2;
- uint x1 = (x - (x0<<2))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return(s->palette[(value >> x1) & (s->cols-1)]);
- }
-
- static void write_pixel_val_2(spr_info_str *s, int x, int y, uint value)
- {
- uint x0 = x>>2;
- uint x1 = (x - (x0<<2))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- value = (value << x1) | (oldval & ~((s->cols-1) << x1));
- s->spr_data[off] = value;
- }
-
- static void write_pixel_rgb_2(spr_info_str *s, int x, int y, uint value)
- {
- pix_str pix;
- uint x0 = x>>2;
- uint x1 = (x - (x0<<2))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- pix.red = (value >> 8) & 0xFF;
- pix.green = (value >> 16) & 0xFF;
- pix.blue = (value >> 24) & 0xFF;
- s->spr_data[off] = (s->closest_rgb(s, &pix)->value << x1)
- | (oldval & ~((s->cols-1) << x1));
- }
- static uint read_pixel_val_4(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>1;
- uint x1 = (x - (x0<<1))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return((value >> x1) & (s->cols-1));
- }
-
- static uint read_pixel_rgb_4(spr_info_str *s, int x, int y)
- {
- uint x0 = x>>1;
- uint x1 = (x - (x0<<1))*s->bpp;
- uint value = s->spr_data[s->line_size*y + x0];
- return(s->palette[(value >> x1) & (s->cols-1)]);
- }
-
- static void write_pixel_val_4(spr_info_str *s, int x, int y, uint value)
- {
- uint x0 = x>>1;
- uint x1 = (x - (x0<<1))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- value = (value << x1) | (oldval & ~((s->cols-1) << x1));
- s->spr_data[off] = value;
- }
-
- static void write_pixel_rgb_4(spr_info_str *s, int x, int y, uint value)
- {
- pix_str pix;
- uint x0 = x>>1;
- uint x1 = (x - (x0<<1))*s->bpp;
- uint off = s->line_size*y + x0;
- uint oldval = s->spr_data[off];
- pix.red = (value >> 8) & 0xFF;
- pix.green = (value >> 16) & 0xFF;
- pix.blue = (value >> 24) & 0xFF;
- s->spr_data[off] = (s->closest_rgb(s, &pix)->value << x1)
- | (oldval & ~((s->cols-1) << x1));
- }
-
- static uint read_pixel_val_8(spr_info_str *s, int x, int y)
- {
- return(s->spr_data[s->line_size*y + x]);
- }
-
- static uint read_pixel_rgb_8(spr_info_str *s, int x, int y)
- {
- return(s->palette[s->spr_data[s->line_size*y + x]]);
- }
-
- static void write_pixel_val_8(spr_info_str *s, int x, int y, uint value)
- {
- s->spr_data[s->line_size*y + x] = value;
- }
-
- static void write_pixel_rgb_8(spr_info_str *s, int x, int y, uint value)
- {
- pix_str pix;
- pix.red = (value >> 8) & 0xFF;
- pix.green = (value >> 16) & 0xFF;
- pix.blue = (value >> 24) & 0xFF;
- s->spr_data[s->line_size*y + x] = s->closest_rgb(s, &pix)->value;
- }
-
-
- static uint read_pixel_val_15(spr_info_str *s, int x, int y)
- {
- return( s->spr_data[s->line_size*y + (x<<1)] +
- (s->spr_data[s->line_size*y + (x<<1)+1] << 8));
- }
-
- static uint read_pixel_rgb_15(spr_info_str *s, int x, int y)
- {
- uint value, r,g,b;
-
- value = s->spr_data[s->line_size*y + (x<<1)] +
- (s->spr_data[s->line_size*y + (x<<1)+1] << 8);
-
- /* extract 5 bit colour fields from index */
-
- r = (value >> 0) & 0x1F;
- g = (value >> 5) & 0x1F;
- b = (value >> 10) & 0x1F;
-
- /* convert 5 bit to 8 bit using */
- /* upper 3 bits for lower 3 bits */
-
- r = (r << 3) | (r >> 2);
- g = (g << 3) | (g >> 2);
- b = (b << 3) | (b >> 2);
-
- return( (b<<24) | (g<<16) | (r<<8) );
- }
-
- static void write_pixel_val_15(spr_info_str *s, int x, int y, uint value)
- {
- s->spr_data[s->line_size*y + (x<<1)] = value;
- s->spr_data[s->line_size*y + (x<<1)+1] = value >> 8;
- }
-
- static void write_pixel_rgb_15(spr_info_str *s, int x, int y, uint value)
- {
- pix_str pix;
- pix.red = (value >> 8) & 0xFF;
- pix.green = (value >> 16) & 0xFF;
- pix.blue = (value >> 24) & 0xFF;
- value = s->closest_rgb(s, &pix)->value;
- s->spr_data[s->line_size*y + (x<<1)] = value;
- s->spr_data[s->line_size*y + (x<<1)+1] = value >> 8;
- }
-
- static uint read_pixel_24_24(spr_info_str *s, int x, int y)
- {
- int off = s->line_size*y + x*3;
- return((s->spr_data[off] << 8) |
- (s->spr_data[off+1] << 16) |
- (s->spr_data[off+2] << 24));
- }
-
- static void write_pixel_24_24(spr_info_str *s, int x, int y, uint value)
- {
- int off = s->line_size*y + x*3;
- s->spr_data[off] = value >> 8;
- s->spr_data[off+1] = value >> 16;
- s->spr_data[off+2] = value >> 24;
- }
-
- static uint read_pixel_24_32_LE(spr_info_str *s, int x, int y)
- {
- uint value = *((int*)&s->spr_data[s->line_size*y + (x<<2)]);
-
- /* xxBBGGRR to BBGGRRxx */
- return((value << 8) | (value >> 24));
- }
-
- static uint read_pixel_24_32_BE(spr_info_str *s, int x, int y)
- {
- uint value=swap_endian(*((int*)&s->spr_data[s->line_size*y+(x<<2)]));
-
- /* xxBBGGRR to BBGGRRxx */
- return((value << 8) | (value >> 24));
- }
-
- static void write_pixel_24_32_LE(spr_info_str *s, int x, int y, uint value)
- {
- /* BBGGRRxx to xxBBGGRR */
- *((uint*)&s->spr_data[s->line_size*y + (x<<2)]) = (value >> 8) |
- (value << 24);
- }
-
- static void write_pixel_24_32_BE(spr_info_str *s, int x, int y, uint value)
- {
- /* BBGGRRxx to xxBBGGRR */
- *((uint*)&s->spr_data[s->line_size*y + (x<<2)]) =
- swap_endian((value >> 8) | (value >> 24));
- }
-
- static pix_str *default_closest_rgb(spr_info_str *s, pix_str *p)
- {
- p = p;
-
- fprintf(stderr,"closest_rgb function pointer not set up (%08X)\n",
- (int)s);
- exit(1);
-
- return(0);
- }
-
- /*
- * calculate the best functions to use for
- * reading and writing pixels
- *
- * NOTE: the write_pixel_RGB functions require
- * the closest_rgb function pointer to
- * be set up AFTER calling this function
- */
-
- void spr_init_funcs(spr_info_str *sinfo)
- {
- switch(sinfo->bpp)
- {
- case 1:
- sinfo->read_pixel_val = read_pixel_val_1;
- sinfo->read_pixel_rgb = read_pixel_rgb_1;
- sinfo->write_pixel_val = write_pixel_val_1;
- sinfo->write_pixel_rgb = write_pixel_rgb_1;
- break;
-
- case 2:
- sinfo->read_pixel_val = read_pixel_val_2;
- sinfo->read_pixel_rgb = read_pixel_rgb_2;
- sinfo->write_pixel_val = write_pixel_val_2;
- sinfo->write_pixel_rgb = write_pixel_rgb_2;
- break;
-
- case 4:
- sinfo->read_pixel_val = read_pixel_val_4;
- sinfo->read_pixel_rgb = read_pixel_rgb_4;
- sinfo->write_pixel_val = write_pixel_val_4;
- sinfo->write_pixel_rgb = write_pixel_rgb_4;
- break;
-
- case 8:
- sinfo->read_pixel_val = read_pixel_val_8;
- sinfo->read_pixel_rgb = read_pixel_rgb_8;
- sinfo->write_pixel_val = write_pixel_val_8;
- sinfo->write_pixel_rgb = write_pixel_rgb_8;
- break;
-
- case 15:
- sinfo->read_pixel_val = read_pixel_val_15;
- sinfo->read_pixel_rgb = read_pixel_rgb_15;
- sinfo->write_pixel_val = write_pixel_val_15;
- sinfo->write_pixel_rgb = write_pixel_rgb_15;
- break;
-
- case 24:
- if(sinfo->pix == 24)
- {
- sinfo->read_pixel_val = read_pixel_24_24;
- sinfo->read_pixel_rgb = read_pixel_24_24;
- sinfo->write_pixel_val = write_pixel_24_24;
- sinfo->write_pixel_rgb = write_pixel_24_24;
- }
- else
- {
- if(ENDIAN_TYPE == LITTLE_ENDIAN)
- {
- sinfo->read_pixel_val = read_pixel_24_32_LE;
- sinfo->read_pixel_rgb = read_pixel_24_32_LE;
- sinfo->write_pixel_val = write_pixel_24_32_LE;
- sinfo->write_pixel_rgb = write_pixel_24_32_LE;
- }
- else
- {
- sinfo->read_pixel_val = read_pixel_24_32_BE;
- sinfo->read_pixel_rgb = read_pixel_24_32_BE;
- sinfo->write_pixel_val = write_pixel_24_32_BE;
- sinfo->write_pixel_rgb = write_pixel_24_32_BE;
- }
- }
- break;
-
- default:
- break;
- }
-
- sinfo->closest_rgb = default_closest_rgb;
- }
-