/**************************************************************************** * 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; iGetTop(), 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(); }