mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-03 18:15:06 +01:00
463 lines
8.0 KiB
C++
463 lines
8.0 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();
|
|
}
|