#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