/**
* @class Sprite
* @brief Contains information about the drawing of artwork.
* @note All black (0x000000) pixels are transparent.
* @author Sean Kasun
* @date 2000-2001
*/
/*****
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****/
#include "uop.h"
#include <SDL/SDL.h>
#include "sprite.h"
#include "gumps.h"
extern Gumps *gumps;
extern SDL_Surface *screen;
/**
* Create an empty sprite
*/
UOSprite::UOSprite()
{
width=height=0;
data=NULL;
}
/**
* Create a specific sized sprite
* @param w Width of sprite to create
* @param h Height of sprite
*/
UOSprite::UOSprite(Uint16 w,Uint16 h)
{
width=w;
height=h;
data=new Uint16[w*h];
memset((char *)data,0,w*h*2);
}
UOSprite::UOSprite(const UOSprite &sprite)
{
width=sprite.width;
height=sprite.height;
data=new Uint16[width*height];
if (sprite.data)
memcpy(data,sprite.data,width*height*2);
}
Sprite::~Sprite()
{
}
UOSprite::~UOSprite()
{
if (data)
delete[] data;
}
void UOSprite::resize(Uint16 w,Uint16 h)
{
if (data!=NULL)
delete [] data;
width=w;
height=h;
data=new Uint16[w*h];
memset((char *)data,0,w*h*2);
}
void Sprite::blit(Sint16 x, Sint16 y, HueMethod hueMethod, Uint16 hue)
{
Sint16 width=this->width;
Sint16 height=this->height;
Uint16 *data=this->data;
Uint16 *pixels=(Uint16 *)screen->pixels;
Hue &hued = gumps->getHue(hue);
if ((!data) || width<=0 || height<=0)
return;
if (!hue)
hueMethod=HueNone;
if (x<screen->clip_rect.x)
{
data-=(x-screen->clip_rect.x);
width+=x;
x=screen->clip_rect.x;
}
if (y<screen->clip_rect.y)
{
data+=this->width*((-y)-screen->clip_rect.x);
height+=y;
y=screen->clip_rect.y;
}
if (x+width>screen->clip_rect.x+screen->clip_rect.w)
width=(screen->clip_rect.x+screen->clip_rect.w)-x;
if (y+height>screen->clip_rect.y+screen->clip_rect.h)
height=(screen->clip_rect.y+screen->clip_rect.h)-y;
Uint16 syStep=(screen->pitch>>1)-width;
Uint16 dStep=this->width-width;
pixels+=x;
pixels+=(screen->pitch>>1)*y;
Uint16 color;
Uint8 red,green,blue,grey;
Uint16 sy;
switch (hueMethod)
{
case HueNone:
for (sy=0;sy<height;sy++,pixels+=syStep,data+=dStep)
for (Uint16 sx=0;sx<width;sx++,pixels++,data++)
if (*data) *pixels=*data;
break;
case HueGreyscale:
for (sy=0;sy<height;sy++,pixels+=syStep,data+=dStep)
for (Uint16 sx=0;sx<width;sx++,pixels++,data++)
if (*data)
{
color=*data;
red=(color>>11)&0x1f;
green=(color>>6)&0x1f;
blue=(color&0x1f);
grey=(Uint8)((red*RGBTOGREY_RED)+
(blue*RGBTOGREY_BLUE)+
(green*RGBTOGREY_GREEN));
*pixels=(grey<<11)|(grey<<6)|(grey);
}
break;
case HuePartial:
for (sy=0;sy<height;sy++,pixels+=syStep,data+=dStep)
for (Uint16 sx=0;sx<width;sx++,pixels++,data++)
if (*data)
{
color=*data;
red=(color>>11)&0x1f;
green=(color>>6)&0x1f;
blue=(color&0x1f);
if (red==green && red==blue)
{
color=hued.colors[red];
color=((color&0x7fe0)<<1)|(color&0x1f);
}
*pixels=color;
}
break;
case HueFull:
Uint8 red;
for (sy=0;sy<height;sy++,pixels+=syStep,data+=dStep)
for (Uint16 sx=0;sx<width;sx++,pixels++,data++)
if (*data)
{
red=(*data>>11)&0x1f;
*pixels=hued.colors[red];
}
break;
}
}