usbloadergx/source/libwiigui/gui_image.cpp
giantpune 9e79c9d99b * remove little unused code
* code cleanup
2010-09-18 23:16:05 +00:00

469 lines
9.8 KiB
C++

/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_image.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImage class.
*/
GuiImage::GuiImage()
{
image = NULL;
width = 0;
height = 0;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage( GuiImageData * img )
{
if ( img )
{
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
}
else
{
image = NULL;
width = 0;
height = 0;
}
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage( u8 * img, int w, int h )
{
image = img;
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_TEXTURE;
}
GuiImage::GuiImage( int w, int h, GXColor c )
{
image = ( u8 * )memalign ( 32, w * h * 4 );
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COLOR;
if ( !image )
return;
int x, y;
for ( y = 0; y < h; y++ )
{
for ( x = 0; x < w; x++ )
{
this->SetPixel( x, y, c );
}
}
int len = w * h * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
DCFlushRange( image, len );
}
GuiImage::GuiImage( GuiImage &srcimage ) : GuiElement()
{
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
image = ( u8 * )memalign ( 32, len );
memcpy( image, srcimage.GetImage(), len );
DCFlushRange( image, len );
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage::GuiImage( GuiImage *srcimage ) : GuiElement()
{
width = srcimage->GetWidth();
height = srcimage->GetHeight();
int len = width * height * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
image = ( u8 * )memalign ( 32, len );
memcpy( image, srcimage->GetImage(), len );
DCFlushRange( image, len );
imageangle = srcimage->GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage &GuiImage::operator=( GuiImage & srcimage )
{
if ( ( imgType == IMAGE_COLOR || imgType == IMAGE_COPY ) && image )
{
free( image );
image = NULL;
}
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
image = ( u8 * )memalign ( 32, len );
memcpy( image, srcimage.GetImage(), len );
DCFlushRange( image, len );
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
return *this;
}
/**
* Destructor for the GuiImage class.
*/
GuiImage::~GuiImage()
{
if ( ( imgType == IMAGE_COLOR || imgType == IMAGE_COPY ) && image )
{
free( image );
image = NULL;
}
}
u8 * GuiImage::GetImage()
{
return image;
}
void GuiImage::SetImage( GuiImageData * img )
{
LOCK( this );
if ( ( imgType == IMAGE_COLOR || imgType == IMAGE_COPY ) && image )
{
free( image );
image = NULL;
}
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
imgType = IMAGE_DATA;
}
void GuiImage::SetImage( u8 * img, int w, int h )
{
LOCK( this );
if ( ( imgType == IMAGE_COLOR || imgType == IMAGE_COPY ) && image )
{
free( image );
image = NULL;
}
image = img;
width = w;
height = h;
imgType = IMAGE_TEXTURE;
}
void GuiImage::SetAngle( float a )
{
LOCK( this );
imageangle = a;
}
float GuiImage::GetAngle()
{
return imageangle;
}
void GuiImage::SetTile( int t )
{
LOCK( this );
tile = t;
}
void GuiImage::SetWidescreen( bool w )
{
LOCK( this );
widescreen = w;
}
void GuiImage::SetParentAngle( bool a )
{
LOCK( this );
parentangle = a;
}
GXColor GuiImage::GetPixel( int x, int y )
{
if ( !image || this->GetWidth() <= 0 || x < 0 || y < 0 )
return ( GXColor ) {0, 0, 0, 0};
u32 offset = ( ( ( y >> 2 ) << 4 ) * this->GetWidth() ) + ( ( x >> 2 ) << 6 ) + ( ( ( y % 4 << 2 ) + x % 4 ) << 1 );
GXColor color;
color.a = *( image + offset );
color.r = *( image + offset + 1 );
color.g = *( image + offset + 32 );
color.b = *( image + offset + 33 );
return color;
}
void GuiImage::SetPixel( int x, int y, GXColor color )
{
LOCK( this );
if ( !image || this->GetWidth() <= 0 || x < 0 || y < 0 )
return;
u32 offset = ( ( ( y >> 2 ) << 4 ) * this->GetWidth() ) + ( ( x >> 2 ) << 6 ) + ( ( ( y % 4 << 2 ) + x % 4 ) << 1 );
*( image + offset ) = color.a;
*( image + offset + 1 ) = color.r;
*( image + offset + 32 ) = color.g;
*( image + offset + 33 ) = color.b;
}
void GuiImage::SetGrayscale( void )
{
LOCK( this );
GXColor color;
u32 offset, gray;
for ( int x = 0; x < width; x++ )
{
for ( int y = 0; y < height; y++ )
{
offset = ( ( ( y >> 2 ) << 4 ) * width ) + ( ( x >> 2 ) << 6 ) + ( ( ( y % 4 << 2 ) + x % 4 ) << 1 );
color.r = *( image + offset + 1 );
color.g = *( image + offset + 32 );
color.b = *( image + offset + 33 );
gray = ( 77 * color.r + 150 * color.g + 28 * color.b ) / 255;
*( image + offset + 1 ) = gray;
*( image + offset + 32 ) = gray;
*( image + offset + 33 ) = gray;
}
}
int len = width * height * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
DCFlushRange( image, len );
}
void GuiImage::SetStripe( int s )
{
LOCK( this );
stripe = s;
}
void GuiImage::SetSkew( int XX1, int YY1, int XX2, int YY2, int XX3, int YY3, int XX4, int YY4 )
{
xx1 = XX1;
yy1 = YY1;
xx2 = XX2;
yy2 = YY2;
xx3 = XX3;
yy3 = YY3;
xx4 = XX4;
yy4 = YY4;
}
void GuiImage::SetSkew( int *skew )
{
xx1 = *skew++;
yy1 = *skew++;
xx2 = *skew++;
yy2 = *skew++;
xx3 = *skew++;
yy3 = *skew++;
xx4 = *skew++;
yy4 = *skew;
}
void GuiImage::ColorStripe( int shift )
{
LOCK( this );
int x, y;
GXColor color;
int alt = 0;
for ( y = 0; y < this->GetHeight(); y++ )
{
if ( y % 3 == 0 )
alt ^= 1;
for ( x = 0; x < this->GetWidth(); x++ )
{
color = GetPixel( x, y );
if ( alt )
{
if ( color.r < 255 - shift )
color.r += shift;
else
color.r = 255;
if ( color.g < 255 - shift )
color.g += shift;
else
color.g = 255;
if ( color.b < 255 - shift )
color.b += shift;
else
color.b = 255;
color.a = 255;
}
else
{
if ( color.r > shift )
color.r -= shift;
else
color.r = 0;
if ( color.g > shift )
color.g -= shift;
else
color.g = 0;
if ( color.b > shift )
color.b -= shift;
else
color.b = 0;
color.a = 255;
}
SetPixel( x, y, color );
}
}
int len = width * height * 4;
if ( len % 32 ) len += ( 32 - len % 32 );
DCFlushRange( image, len );
}
/**
* Draw the button on screen
*/
void GuiImage::Draw()
{
LOCK( this );
if ( !image || !this->IsVisible() || tile == 0 )
return;
float currScale = this->GetScale();
int currLeft = this->GetLeft();
float currAngleDyn = this->GetAngleDyn();
if ( currAngleDyn && parentangle )
imageangle = currAngleDyn;
if ( tile > 0 )
{
for ( int i = 0; i < tile; i++ )
Menu_DrawImg( currLeft + width*i, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4 );
}
else
{
// temporary (maybe), used to correct offset for scaled images
if ( scale != 1 )
currLeft = currLeft - width / 2 + ( width * scale ) / 2;
Menu_DrawImg( currLeft, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4 );
}
if ( stripe > 0 )
for ( int y = 0; y < this->GetHeight(); y += 6 )
Menu_DrawRectangle( currLeft, this->GetTop() + y, this->GetWidth(), 3, ( GXColor ) {0, 0, 0, stripe}, 1 );
this->UpdateEffects();
}