*Made a Buffer Thread for the Carousell to load covers. Now there is no GameLimit anymore, no long loading time and no such memory usuage by it.

*Removed the temporary AltDol Fix
This commit is contained in:
dimok321 2009-07-12 14:02:48 +00:00
parent 46791e8ab2
commit 50231648ca
12 changed files with 958 additions and 199 deletions

File diff suppressed because one or more lines are too long

298
source/buffer.cpp Normal file
View File

@ -0,0 +1,298 @@
/****************************************************************************
* USB Loader GX Team
* buffer.cpp
*
* Loading covers in a background thread
***************************************************************************/
#include <gccore.h>
#include <unistd.h>
#include "libwiigui/gui.h"
#include "usbloader/disc.h"
#include "settings/cfg.h"
#include "buffer.h"
#include "main.h"
#define BUFFERSIZE 9
extern struct discHdr * gameList;
extern u32 gameCnt;
static lwp_t bufferthread = LWP_THREAD_NULL;
static bool BufferHalt = true;
static int loading = 0;
static int offset = 0;
static int direction = 1;
static bool changed = false;
static bool firstime = true;
static GuiImageData NoCoverData(nocover_png);
static GuiImageData * cover[BUFFERSIZE];
static GuiImage * coverImg[BUFFERSIZE];
static GuiImage * NoCover[BUFFERSIZE];
GuiImage * ImageBuffer(int imagenumber)
{
if((BUFFERSIZE-1 > imagenumber) && direction >= 0) {
return coverImg[imagenumber];
}
if((0 < imagenumber) && direction < 0) {
return coverImg[imagenumber];
}
if(loading == BUFFERSIZE) {
return coverImg[imagenumber];
}
return NoCover[imagenumber];
}
void LoadImages()
{
if(!changed || BufferHalt)
return;
char ID[4];
char IDfull[7];
char imgPath[200];
for(u32 i = offset; (int) i < offset+BUFFERSIZE; i++) {
struct discHdr *header;
if(i > gameCnt-1)
header = &gameList[i-gameCnt];
else
header = &gameList[i];
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, IDfull); //Load full id image
//firsttime loading images into memory
if(firstime) {
if(coverImg[loading]) {
delete coverImg[loading];
coverImg[loading] = NULL;
}
if(cover[loading]) {
delete cover[loading];
cover[loading] = NULL;
}
cover[loading] = new GuiImageData(imgPath,0);
if (!cover[loading]->GetImage()) {
delete cover[loading];
cover[loading] = NULL;
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); //Load short id image
cover[loading] = new GuiImageData(imgPath, 0);
if (!cover[loading]->GetImage()) {
delete cover[loading];
cover[loading] = NULL;
snprintf(imgPath, sizeof(imgPath), "%snoimage.png", Settings.covers_path); //Load no image
cover[loading] = new GuiImageData(imgPath, nocover_png);
}
}
coverImg[loading] = new GuiImage(cover[loading]);
} else {
if(direction >= 0) {
if(loading < BUFFERSIZE-1) {
if(coverImg[loading]) {
delete coverImg[loading];
coverImg[loading] = NULL;
}
if(loading == 0) {
if(cover[loading]) {
delete cover[loading];
cover[loading] = NULL;
}
cover[loading] = new GuiImageData(NULL, 0);
cover[loading] = cover[loading+1];
} else {
cover[loading] = cover[loading+1];
}
coverImg[loading] = new GuiImage(cover[loading]);
} else {
cover[loading] = new GuiImageData(imgPath,0);
if (!cover[loading]->GetImage()) {
delete cover[loading];
cover[loading] = NULL;
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); //Load short id image
cover[loading] = new GuiImageData(imgPath, 0);
if (!cover[loading]->GetImage()) {
delete cover[loading];
cover[loading] = NULL;
snprintf(imgPath, sizeof(imgPath), "%snoimage.png", Settings.covers_path); //Load no image
cover[loading] = new GuiImageData(imgPath, nocover_png);
}
}
if(coverImg[loading]) {
delete coverImg[loading];
coverImg[loading] = NULL;
}
coverImg[loading] = new GuiImage(cover[loading]);
}
} else if(direction < 0) {
if(BUFFERSIZE-loading-1 > 0) {
if(coverImg[BUFFERSIZE-loading-1]) {
delete coverImg[BUFFERSIZE-loading-1];
coverImg[BUFFERSIZE-loading-1] = NULL;
}
if(BUFFERSIZE-loading-1 == BUFFERSIZE-1) {
if(cover[BUFFERSIZE-loading-1]) {
delete cover[BUFFERSIZE-loading-1];
cover[BUFFERSIZE-loading-1] = NULL;
}
cover[BUFFERSIZE-loading-1] = new GuiImageData(NULL, 0);
cover[BUFFERSIZE-loading-1] = cover[BUFFERSIZE-loading-1-1];
} else {
cover[BUFFERSIZE-loading-1] = cover[BUFFERSIZE-loading-1-1];
coverImg[BUFFERSIZE-loading-1] = new GuiImage(cover[BUFFERSIZE-loading-1]);
}
} else {
header = &gameList[offset];
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, IDfull); //Load full id image
cover[0] = new GuiImageData(imgPath,0);
if (!cover[0]->GetImage()) {
delete cover[0];
cover[0] = NULL;
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); //Load short id image
cover[0] = new GuiImageData(imgPath, 0);
if (!cover[0]->GetImage()) {
delete cover[0];
cover[0] = NULL;
snprintf(imgPath, sizeof(imgPath), "%snoimage.png", Settings.covers_path); //Load no image
cover[0] = new GuiImageData(imgPath, nocover_png);
}
}
if(coverImg[0]) {
delete coverImg[0];
coverImg[0] = NULL;
}
coverImg[0] = new GuiImage(cover[0]);
}
}
}
loading++;
}
loading = BUFFERSIZE;
changed = false;
firstime = false;
}
void NewOffset(int off, int d)
{
if(offset == off || loading < BUFFERSIZE)
return;
direction = d;
offset = off;
loading = 0;
changed = true;
}
/****************************************************************************
* HaltBuffer
***************************************************************************/
void HaltBufferThread()
{
BufferHalt = true;
firstime = true;
changed = true;
loading = 0;
offset = 0;
direction = 0;
// wait for thread to finish
while(!LWP_ThreadIsSuspended(bufferthread))
usleep(100);
for(int i = 0; i < BUFFERSIZE; i++) {
delete cover[i];
cover[i] = NULL;
delete coverImg[i];
coverImg[i] = NULL;
delete NoCover[i];
NoCover[i] = NULL;
}
}
/****************************************************************************
* ResumeBufferThread
***************************************************************************/
void ResumeBufferThread(int offset)
{
BufferHalt = false;
firstime = true;
changed = true;
loading = 0;
offset = offset;
direction = 0;
for(u8 i = 0; i < BUFFERSIZE; i++) {
if(NoCover[i] != NULL) {
delete NoCover[i];
NoCover[i] = NULL;
}
NoCover[i] = new GuiImage(&NoCoverData);
}
LWP_ResumeThread(bufferthread);
}
/*********************************************************************************
* Bufferthread
*********************************************************************************/
static void * bufferinitcallback(void *arg)
{
while(1)
{
if(BufferHalt)
LWP_SuspendThread(bufferthread);
LoadImages();
}
return NULL;
}
/****************************************************************************
* InitBufferThread with priority 50
***************************************************************************/
void InitBufferThread()
{
LWP_CreateThread(&bufferthread, bufferinitcallback, NULL, NULL, 0, 50);
}
/****************************************************************************
* ShutdownThread
***************************************************************************/
void ShutdownBufferThread()
{
LWP_JoinThread (bufferthread, NULL);
bufferthread = LWP_THREAD_NULL;
}

18
source/buffer.h Normal file
View File

@ -0,0 +1,18 @@
/****************************************************************************
* USB Loader GX Team
* buffer.cpp
*
* Loading covers in a background thread
***************************************************************************/
#ifndef BUFFER_H
#define BUFFER_H
GuiImage * ImageBuffer(int imagenumber);
void NewOffset(int off, int d);
void InitBufferThread();
void ShutdownBufferThread();
void ResumeBufferThread(int offset);
void HaltBufferThread();
#endif

365
source/libwiigui/cover.cpp Normal file
View File

@ -0,0 +1,365 @@
/****************************************************************************
* Cover Class
* by dimok
***************************************************************************/
#include "cover.h"
/**
* Constructor for the CoverImage class.
*/
CoverImage::CoverImage(const char * imgPath, const u8 * buffer)
{
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;
if(imgPath)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromDevice(imgPath);
if(ctx)
{
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
if(image)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, image, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(image, len);
}
else
{
free(image);
image = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
if (!image) //use buffer data instead
{
width = 0;
height = 0;
if(buffer)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(buffer);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
if(image)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, image, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(image, len);
}
else
{
free(image);
image = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
imgType = IMAGE_COPY;
}
CoverImage::CoverImage(u8 * img, int w, int h)
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
width = w;
height = h;
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, img, len);
DCFlushRange(image, len);
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_COPY;
}
CoverImage::CoverImage(GuiImageData * img)
{
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
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;
}
CoverImage::CoverImage(CoverImage &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;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
CoverImage::CoverImage(CoverImage *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;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
CoverImage &CoverImage::operator=(CoverImage &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;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
return *this;
}
/**
* Destructor for the CoverImage class.
*/
CoverImage::~CoverImage()
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
}
u8 * CoverImage::GetImage()
{
return image;
}
void CoverImage::SetAngle(float a)
{
LOCK(this);
imageangle = a;
}
float CoverImage::GetAngle()
{
return imageangle;
}
void CoverImage::SetTile(int t)
{
LOCK(this);
tile = t;
}
void CoverImage::SetWidescreen(bool w)
{
LOCK(this);
widescreen = w;
}
GXColor CoverImage::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 CoverImage::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 CoverImage::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;
}
/**
* Draw the button on screen
*/
void CoverImage::Draw()
{
LOCK(this);
if(!image || !this->IsVisible() || tile == 0)
return;
float currScale = this->GetScale();
int currLeft = this->GetLeft();
float currAngleDyn = this->GetAngleDyn();
if(currAngleDyn)
imageangle = currAngleDyn;
if(tile > 0)
{
for(int i=0; i<tile; i++)
Menu_DrawImg(currLeft+width*i, this->GetTop(), 0, 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(), 0, 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();
}

100
source/libwiigui/cover.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef COVER_H
#define COVER_H
#include "gui.h"
//!Display, manage, and manipulate images in the GUI
class CoverImage : public GuiElement
{
public:
//!Constructor
CoverImage(const char * imgPath, const u8 * buffer);
//!\overload
//!Sets up a new image from the image data specified
//!\param img
//!\param w Image width
//!\param h Image height
CoverImage(u8 * img, int w, int h);
CoverImage(GuiImageData *img);
//!\overload
//!Creates an image filled with the specified color
//!\param w Image width
//!\param h Image height
//!\param c Image color
CoverImage(int w, int h, GXColor c);
//! Copy Constructor
CoverImage(CoverImage &srcimage);
CoverImage(CoverImage *srcimage);
//! = operator for copying images
CoverImage &operator=(CoverImage &srcimage);
//!Destructor
~CoverImage();
//!Sets the image rotation angle for drawing
//!\param a Angle (in degrees)
void SetAngle(float a);
//!Gets the image rotation angle for drawing
float GetAngle();
//!Sets the number of times to draw the image horizontally
//!\param t Number of times to draw the image
void SetTile(int t);
// true set horizontal scale to 0.8 //added
void SetWidescreen(bool w);
//!Constantly called to draw the image
void Draw();
//!Gets the image data
//!\return pointer to image data
u8 * GetImage();
//!Sets up a new image using the CoverImageData object specified
//!\param img Pointer to CoverImageData object
void SetImage(GuiImageData * img);
//!\overload
//!\param img Pointer to image data
//!\param w Width
//!\param h Height
void SetImage(u8 * img, int w, int h);
//!Gets the pixel color at the specified coordinates of the image
//!\param x X coordinate
//!\param y Y coordinate
GXColor GetPixel(int x, int y);
//!Sets the pixel color at the specified coordinates of the image
//!\param x X coordinate
//!\param y Y coordinate
//!\param color Pixel color
void SetPixel(int x, int y, GXColor color);
//!Directly modifies the image data to create a color-striped effect
//!Alters the RGB values by the specified amount
//!\param s Amount to increment/decrement the RGB values in the image
void ColorStripe(int s);
//!Sets a stripe effect on the image, overlaying alpha blended rectangles
//!Does not alter the image data
//!\param s Alpha amount to draw over the image
void SetStripe(int s);
s32 z;
void SetSkew(int XX1, int YY1,int XX2, int YY2,int XX3, int YY3,int XX4, int YY4);
int xx1;
int yy1;
int xx2;
int yy2;
int xx3;
int yy3;
int xx4;
int yy4;
int rxx1;
int ryy1;
int rxx2;
int ryy2;
int rxx3;
int ryy3;
int rxx4;
int ryy4;
protected:
int imgType; //!< Type of image data (IMAGE_TEXTURE, IMAGE_COLOR, IMAGE_DATA)
u8 * image; //!< Poiner to image data. May be shared with CoverImageData data
f32 imageangle; //!< Angle to draw the image
int tile; //!< Number of times to draw (tile) the image horizontally
int stripe; //!< Alpha value (0-255) to apply a stripe effect to the texture
short widescreen; //added
};
#endif

View File

@ -84,7 +84,8 @@ enum
{
IMAGE_TEXTURE,
IMAGE_COLOR,
IMAGE_DATA
IMAGE_DATA,
IMAGE_COPY
};
enum
@ -593,6 +594,11 @@ class GuiImage : public GuiElement
//!\param h Image height
//!\param c Image color
GuiImage(int w, int h, GXColor c);
//! Copy Constructor
GuiImage(GuiImage &srcimage);
GuiImage(GuiImage *srcimage);
//! = operator for copying images
GuiImage &operator=(GuiImage &srcimage);
//!Destructor
~GuiImage();
//!Sets the image rotation angle for drawing

View File

@ -13,6 +13,7 @@
#include "gui_gamecarousel.h"
#include "../settings/cfg.h"
#include "../main.h"
#include "../buffer.h"
#include <string.h>
#include <math.h>
@ -22,9 +23,9 @@
#define DEG_OFFSET 7
#define RADIUS 780
#define IN_SPEED 175
#define SHIFT_SPEED 100
#define SHIFT_SPEED 75
#define SPEED_STEP 4
#define SAFETY 320
#define SPEED_LIMIT 250
/**
* Constructor for the GuiGameCarousel class.
@ -33,7 +34,7 @@ GuiGameCarousel::GuiGameCarousel(int w, int h, struct discHdr * l, int count, co
{
width = w;
height = h;
gameCnt = (count < SAFETY) ? count : SAFETY;
gameCnt = count;
gameList = l;
pagesize = (gameCnt < PAGESIZE) ? gameCnt : PAGESIZE;
listOffset = (offset == 0) ? this->FindMenuItem(-1, 1) : offset;
@ -94,49 +95,18 @@ GuiGameCarousel::GuiGameCarousel(int w, int h, struct discHdr * l, int count, co
btnRight->SetTrigger(trigPlus);
btnRight->SetEffectGrow();
ResumeBufferThread(listOffset);
gameIndex = new int[pagesize];
game = new GuiButton * [pagesize];
bob = new int[pagesize];
coverImg = new GuiImage * [gameCnt];
cover = new GuiImageData * [gameCnt];
for(int i=0; i<pagesize; i++) {
bob[i]=i;
}
char ID[4];
char IDfull[7];
for(int i=0; i < gameCnt; i++) {
struct discHdr *header = &gameList[i];
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, IDfull); //Load full id image
cover[i] = new GuiImageData(imgPath,0);
if (!cover[i]->GetImage()) {
delete cover[i];
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); //Load short id image
cover[i] = new GuiImageData(imgPath, 0);
if (!cover[i]->GetImage()) {
delete cover[i];
snprintf(imgPath, sizeof(imgPath), "%snoimage.png", Settings.covers_path); //Load no image
cover[i] = new GuiImageData(imgPath, nocover_png);
}
}
coverImg[i] = new GuiImage(cover[i]);
coverImg[i]->SetScale(SCALE);
coverImg[i]->SetWidescreen(CFG.widescreen);
}
for(int i=0; i < pagesize; i++) {
game[i] = new GuiButton(122,244);
game[i]->SetParent(this);
game[i]->SetAlignment(ALIGN_CENTRE,ALIGN_MIDDLE);
game[i]->SetPosition(0,740);
game[i]->SetImage(coverImg[(listOffset+i) % gameCnt]);
game[i]->SetImage(ImageBuffer((listOffset+i) % gameCnt));
game[i]->SetScale(SCALE);
game[i]->SetRumble(false);
game[i]->SetTrigger(trigA);
game[i]->SetSoundClick(btnSoundClick);
@ -151,6 +121,7 @@ GuiGameCarousel::GuiGameCarousel(int w, int h, struct discHdr * l, int count, co
*/
GuiGameCarousel::~GuiGameCarousel()
{
HaltBufferThread();
delete imgRight;
delete imgLeft;
@ -170,16 +141,9 @@ GuiGameCarousel::~GuiGameCarousel()
for(int i=0; i<pagesize; i++) {
delete game[i];
}
for(int i=0; i<gameCnt; i++) {
delete coverImg[i];
delete cover[i];
}
delete [] gameIndex;
delete [] bob;
delete [] game;
delete [] coverImg;
delete [] cover;
}
@ -192,7 +156,7 @@ void GuiGameCarousel::SetFocus(int f)
game[i]->ResetState();
if(f == 1)
game[bob[selectedItem]]->SetState(STATE_SELECTED);
game[selectedItem]->SetState(STATE_SELECTED);
}
@ -220,12 +184,12 @@ int GuiGameCarousel::GetClickedOption()
{
int found = -1;
if (clickedItem>=0 && clickedItem<=pagesize){
if (game[bob[(clickedItem+1) % pagesize]]->GetState()==STATE_SELECTED){
if (game[(clickedItem+1) % pagesize]->GetState()==STATE_SELECTED){
found = (clickedItem+listOffset+1) % gameCnt;
game[bob[(clickedItem+1) % pagesize]]->SetState(STATE_SELECTED);
game[bob[clickedItem]]->SetState(STATE_SELECTED);
game[(clickedItem+1) % pagesize]->SetState(STATE_SELECTED);
game[clickedItem]->SetState(STATE_SELECTED);
} else {
game[bob[clickedItem]]->SetState(STATE_SELECTED);
game[clickedItem]->SetState(STATE_SELECTED);
found= (clickedItem+listOffset) % gameCnt;}
clickedItem=-1;
}
@ -237,8 +201,8 @@ int GuiGameCarousel::GetSelectedOption()
{
int found = -1;
for(int i=pagesize-1; i>-1; i--) {
if(game[bob[i]]->GetState() == STATE_SELECTED) {
game[bob[i]]->SetState(STATE_SELECTED);
if(game[i]->GetState() == STATE_SELECTED) {
game[i]->SetState(STATE_SELECTED);
found = (listOffset+i) % gameCnt;
break;
}
@ -283,7 +247,8 @@ void GuiGameCarousel::Draw()
for(int i=0; i<pagesize; i++) {
if(next >= 0) {
game[bob[i]]->Draw();
game[i]->SetImage(ImageBuffer(i));
game[i]->Draw();
next = this->FindMenuItem(next, 1);
} else break;
}
@ -309,43 +274,51 @@ void GuiGameCarousel::Update(GuiTrigger * t)
}
}
if(speed > SPEED_LIMIT)
speed = SPEED_LIMIT;
btnRight->Update(t);
btnLeft->Update(t);
if(btnRight->GetState() == STATE_CLICKED)
NewOffset(listOffset, -1);
else if(btnLeft->GetState() == STATE_CLICKED)
NewOffset(listOffset, 1);
int next = listOffset;
for(int i=0; i<pagesize; i++) {
if(next >= 0) {
if(game[bob[i]]->GetState() == STATE_DISABLED) {
game[bob[i]]->SetVisible(true);
game[bob[i]]->SetState(STATE_DEFAULT);
if(game[i]->GetState() == STATE_DISABLED) {
game[i]->SetVisible(true);
game[i]->SetState(STATE_DEFAULT);
}
gameIndex[i] = next;
next = this->FindMenuItem(next, 1);
} else {
game[bob[i]]->SetVisible(false);
game[bob[i]]->SetState(STATE_DISABLED);
game[i]->SetVisible(false);
game[i]->SetState(STATE_DISABLED);
}
if(focus) {
if(i != selectedItem && game[bob[i]]->GetState() == STATE_SELECTED)
game[bob[i]]->ResetState();
else if(i == selectedItem && game[bob[i]]->GetState() == STATE_DEFAULT);
game[bob[selectedItem]]->SetState(STATE_SELECTED, t->chan);
if(i != selectedItem && game[i]->GetState() == STATE_SELECTED)
game[i]->ResetState();
else if(i == selectedItem && game[i]->GetState() == STATE_DEFAULT);
game[selectedItem]->SetState(STATE_SELECTED, t->chan);
}
game[bob[i]]->Update(t);
game[i]->Update(t);
if(game[bob[i]]->GetState() == STATE_SELECTED) {
if(game[i]->GetState() == STATE_SELECTED) {
selectedItem = i;
}
if(game[bob[i]]->GetState() == STATE_CLICKED) {
if(game[i]->GetState() == STATE_CLICKED) {
clickedItem = i;
}
}
// navigation
if(!focus || gameCnt <= pagesize || (game[bob[0]]->GetEffect() && game[bob[pagesize-1]]->GetEffect()))
if(!focus || gameCnt <= pagesize || (game[0]->GetEffect() && game[pagesize-1]->GetEffect()))
return; // skip navigation
if (((btnLeft->GetState() == STATE_CLICKED) &&(Settings.xflip!=sysmenu)&&(Settings.xflip!=yes))
@ -367,23 +340,15 @@ void GuiGameCarousel::Update(GuiTrigger * t)
listOffset = (listOffset+1 < gameCnt) ? listOffset+1 : 0;
firstPic = (firstPic+1 < pagesize) ? firstPic+1 : 0;
for (int i=0; i<pagesize; i++) {
bob[i] = (firstPic+i)%pagesize;
}
game[bob[pagesize-1]]->SetImage(coverImg[(listOffset + pagesize-1) % gameCnt]);
game[bob[pagesize-1]]->SetPosition(0, RADIUS);
game[pagesize-1]->SetPosition(0, RADIUS);
for (int i=0; i<pagesize; i++) {
game[bob[i]]->SetEffect(EFFECT_GOROUND, -speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i-3)*DEG_OFFSET/2, 1, 0, RADIUS);
game[i]->SetEffect(EFFECT_GOROUND, -speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i-3)*DEG_OFFSET/2, 1, 0, RADIUS);
}
speed+=SPEED_STEP;
}
else if (((btnRight->GetState() == STATE_CLICKED) &&(Settings.xflip!=sysmenu)&&(Settings.xflip!=yes))
||((btnLeft->GetState() == STATE_CLICKED) &&((Settings.xflip==sysmenu)||(Settings.xflip==yes)))){
@ -402,15 +367,10 @@ void GuiGameCarousel::Update(GuiTrigger * t)
listOffset = (listOffset-1 < 0) ? gameCnt-1 : listOffset-1;
firstPic = (firstPic-1 < 0) ? pagesize-1 : firstPic-1;
for(int i=0; i<pagesize; i++) {
bob[i] = (firstPic+i)%pagesize;
}
game[bob[0]]->SetImage(coverImg[listOffset]);
game[bob[0]]->SetPosition(0, RADIUS);
game[0]->SetPosition(0, RADIUS);
for(int i=0; i<pagesize; i++) {
game[bob[i]]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i+1)*DEG_OFFSET/2, 1, 0, RADIUS);
game[i]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i+1)*DEG_OFFSET/2, 1, 0, RADIUS);
}
speed+=SPEED_STEP;
}
@ -420,83 +380,3 @@ void GuiGameCarousel::Update(GuiTrigger * t)
}
void GuiGameCarousel::Reload(struct discHdr * l, int count)
{
for(int i=0; i<pagesize; i++) {
delete game[i];
}
for(int i=0; i<gameCnt; i++) {
delete coverImg[i];
delete cover[i];
}
delete [] gameIndex;
delete [] bob;
delete [] game;
delete [] coverImg;
delete [] cover;
LOCK(this);
gameCnt = (count < SAFETY) ? count : SAFETY;
gameList = l;
pagesize = (gameCnt < PAGESIZE) ? gameCnt : PAGESIZE;
listOffset = this->FindMenuItem(-1, 1);
selectedItem = listOffset;
focus = 1;
firstPic = 0;
clickedItem = -1;
speed = SHIFT_SPEED;
gameIndex = new int[pagesize];
game = new GuiButton * [pagesize];
bob = new int[pagesize];
coverImg = new GuiImage * [gameCnt];
cover = new GuiImageData * [gameCnt];
for(int i=0; i<pagesize; i++) {
bob[i]=i;
}
char ID[4];
char IDfull[7];
char imgPath[100];
for(int i=0; i < gameCnt; i++) {
struct discHdr *header = &gameList[i];
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, IDfull); //Load full id image
cover[i] = new GuiImageData(imgPath,0);
if (!cover[i]->GetImage()) {
delete cover[i];
snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); //Load short id image
cover[i] = new GuiImageData(imgPath, 0);
if (!cover[i]->GetImage()) {
delete cover[i];
snprintf(imgPath, sizeof(imgPath), "%snoimage.png", Settings.covers_path); //Load no image
cover[i] = new GuiImageData(imgPath, nocover_png);
}
}
coverImg[i] = new GuiImage(cover[i]);
coverImg[i]->SetScale(SCALE);
coverImg[i]->SetWidescreen(CFG.widescreen);
}
for(int i=0; i < pagesize; i++) {
game[i] = new GuiButton(122,244);
game[i]->SetParent(this);
game[i]->SetAlignment(ALIGN_CENTRE,ALIGN_MIDDLE);
game[i]->SetPosition(0,740);
game[i]->SetImage(coverImg[i]);
game[i]->SetRumble(false);
game[i]->SetTrigger(trigA);
game[i]->SetSoundClick(btnSoundClick);
game[i]->SetClickable(true);
game[i]->SetEffect(EFFECT_GOROUND, IN_SPEED, 90-(pagesize-2*i-1)*DEG_OFFSET/2, RADIUS, 180, 1, 0, RADIUS);
}
}

View File

@ -32,13 +32,9 @@ class GuiGameCarousel : public GuiElement
int gameCnt;
int * gameIndex;
int * bob;
GuiButton ** game;
GuiImage ** coverImg;
GuiImageData ** cover;
GuiButton * btnRight;
GuiButton * btnLeft;

View File

@ -54,10 +54,10 @@ GuiImage::GuiImage(GuiImageData * img)
GuiImage::GuiImage(u8 * img, int w, int h)
{
image = img;
image = img;
width = w;
height = h;
imageangle = 0;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
@ -108,13 +108,103 @@ GuiImage::GuiImage(int w, int h, GXColor c)
DCFlushRange(image, len);
}
GuiImage::GuiImage(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;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage::GuiImage(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;
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;
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 && image)
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
}
u8 * GuiImage::GetImage()
@ -125,8 +215,11 @@ u8 * GuiImage::GetImage()
void GuiImage::SetImage(GuiImageData * img)
{
LOCK(this);
if(imgType == IMAGE_COLOR && image)
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
@ -136,8 +229,10 @@ void GuiImage::SetImage(GuiImageData * img)
void GuiImage::SetImage(u8 * img, int w, int h)
{
LOCK(this);
if(imgType == IMAGE_COLOR && image)
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img;
width = w;
height = h;

View File

@ -38,6 +38,7 @@
#include "wpad.h"
#include "listfiles.h"
#include "fatmounter.h"
#include "buffer.h"
#include "usbloader/wdvd.h"
@ -196,6 +197,7 @@ void InitGUIThreads()
{
LWP_CreateThread(&guithread, UpdateGUI, NULL, NULL, 0, 70);
InitProgressThread();
InitBufferThread();
}
void ExitGUIThreads()

View File

@ -11,7 +11,6 @@ extern "C"
bool Load_Dol(void **buffer, int* dollen, char * path);
bool Remove_001_Protection(void *Address, int Size);
u32 load_dol_image(void * dolstart);
char hiddenfix[1000][1000]; // temporary fix for alternative dol not working for some people
#ifdef __cplusplus
}
#endif