#include <string.h> #include "sprite.h" #include "objgfx30.h" TogSprite::TogSprite(void) { image = NULL; pal = NULL; imagesize = 0; width = 0; height = 0; bitdepth = 0; RFP = 0; GFP = 0; BFP = 0; AFP = 0; RShift = 0; GShift = 0; BShift = 0; AShift = 0; return; } // TogSprite void TogSprite::get(TGfx0& SrcObject, Int32 x1, Int32 y1, Int32 x2, Int32 y2) { TPixelFmt pixfmt; uInt32 xx,yy,xOfs,yOfs; uInt32 rx1, ry1, rx2, ry2; uInt32 xCount, yCount; void *p; uInt32 bm; // bit multiplier uInt32 MaxX, MaxY; if ((SrcObject.Buffer==NULL) || (SrcObject.LineOfs==NULL)) return; if (image!=NULL) free(image); MaxX = SrcObject.ogGetMaxX(); MaxY = SrcObject.ogGetMaxY(); SrcObject.ogGetPixFmt(pixfmt); bitdepth = pixfmt.BPP; RFP = pixfmt.RedFieldPosition; GFP = pixfmt.GreenFieldPosition; BFP = pixfmt.BlueFieldPosition; AFP = pixfmt.AlphaFieldPosition; RShift = 8-pixfmt.RedMaskSize; GShift = 8-pixfmt.GreenMaskSize; BShift = 8-pixfmt.BlueMaskSize; AShift = 8-pixfmt.AlphaMaskSize; if (bitdepth==8) { if (pal==NULL) new TRGBA[256]; if (pal==NULL) return; memcpy(pal, SrcObject.pal, sizeof(TRGBA)*256); } // if bm = ((bitdepth+7) >> 3); if (x1>x2) { xx = x1; x1 = x2; x2 = xx; } // if if (y1>y2) { yy = y1; y1 = y2; y2 = yy; } // if xCount = abs(x2-x1)+1; yCount = abs(y2-y1)+1; width = xCount; height = yCount; imagesize = xCount*yCount*bm; image = malloc(imagesize); p = image; if ( ((uInt32)x1>MaxX) || ((uInt32)y1>MaxY) || ((uInt32)x2>MaxX) || ((uInt32)y2>MaxY) ) { memset(p,0,imagesize); } // if xOfs = 0; yOfs = 0; if (y1<0) { yCount += y1; ry1 = 0; yOfs = xCount*abs(y1); } else ry1 = y1; if (x1<0) { xCount += x1; rx1 = 0; xOfs = abs(x1); } else rx1 = x1; if (x2>(Int32)MaxX) { xCount -= MaxX-x2+1; rx2 = MaxX; } else rx2 = x2; if (y2>(Int32)MaxY) { yCount -= MaxY-y2+1; ry2=MaxY; } else ry2 = y2; xCount *= bm; for (yy=0; yy<yCount; yy++) { ( (uInt8 *)p ) += xCount; memcpy(p,(uInt8 *)SrcObject.Buffer+SrcObject.LineOfs[ry1+yy]+rx1,xCount); ( (uInt8 *)p ) += xCount; } return; } // TogSprite::get uInt32 TogSprite::getPixel(void * p) { uInt32 result; switch (bitdepth) { case 8: return *(uInt8 *)p; break; case 15: case 16: return *(uInt16 *)p; break; case 24: asm( " xor %%eax, %%eax \n" // xor eax, eax " mov 2(%%edi),%%al \n" // mov al, [edi+2] " shl $16, %%eax \n" // shl eax, 16 " mov (%%edi), %%ax \n" // mov ax, [edi] " mov %%eax, %1 \n" // mov result, eax : : "D" (p), "m" (result) ); return result; break; case 32: return *(uInt32 *)p; break; default: return 0; break; } // switch } // TogSprite::getPixel uInt32 TogSprite::getSize(void) { /* * getSize * * returns the size of the image as it would take on disk. This includes * all header related information (width/height, bitdepth, pixel format, * etc) along with an extra sizeof(uInt32) * for storing the complete size. This allows easy indexing of images, * since you can figure out exactly how much the image will take up on * disk. This function computes the size in the exact order it is on disk. * If the image is 8bpp, then there is a 768 byte palette stored after the * image data along with an extra sizeof(uInt32) for the palette size in * bytes. Currently we store the entire palette, but later I expect we * will add the ability to optimize the palette so only used entries are * stored. * * If you were to store a single bitmap in a file, getSize would equal the * filesize. */ uInt32 tmpsize; char header_ident[4]; tmpsize = sizeof(header_ident)+ sizeof(uInt32)+ // total size sizeof(width)+sizeof(height)+ // width/height sizeof(bitdepth)+ // bitDepth sizeof(RFP)+sizeof(GFP)+sizeof(BFP)+sizeof(AFP)+ // field positions sizeof(RShift)+sizeof(GShift)+sizeof(BShift)+sizeof(AShift)+ // shifters sizeof(imagesize)+ // image size in bytes imagesize; // actual image area in bytes if (bitdepth==8) tmpsize += sizeof(uInt32)+sizeof(TRGBA)*256; return tmpsize; } // TogSprite::getSize bool TogSprite::load(const char * filename) { return loadFrom(filename,0); } // TogSprite::load bool TogSprite::loadFrom(const char * filename, uInt32 offset) { return true; } // TogSprite::loadFrom; bool TogSprite::save(const char * filename) { return saveTo(filename,0); } // TogSprite::save bool TogSprite::saveTo(const char * filename, Int32 offset) { return true; } // TogSprite::saveTo void TogSprite::unpackRGB(uInt32 colour, uInt8& red, uInt8& green, uInt8& blue) { switch (bitdepth) { case 8: if (colour>255) colour&=255; if (pal==NULL) return; red=pal[colour].red; green=pal[colour].green; blue=pal[colour].blue; break; case 15: case 16: red = (uInt8)(colour >> RFP) << RShift; green = (uInt8)(colour >> GFP) << GShift; blue = (uInt8)(colour >> BFP) << BShift; if ((red!=0) && (RShift!=0)) red+=(1 << RShift)-1; if ((green!=0) && (GShift!=0)) green+=(1 << GShift)-1; if ((blue!=0) && (BShift!=0)) blue+=(1 << BShift)-1; break; case 24: case 32: red = (uInt8)(colour >> RFP); green = (uInt8)(colour >> GFP); blue = (uInt8)(colour >> BFP); break; default: red = 0; green = 0; blue = 0; break; } // switch return; } // TogSprite::unpackRGB TogSprite::~TogSprite(void) { if (image!=NULL) free(image); if (pal!=NULL) delete [] pal; image = NULL; pal = NULL; imagesize = 0; width = 0; height = 0; bitdepth = 0; RFP = 0; GFP = 0; BFP = 0; AFP = 0; RShift = 0; GShift = 0; BShift = 0; AShift = 0; return; } // TogSprite::~TogSprite