WiiFlow_Lite/source/gui/gui.cpp

1051 lines
30 KiB
C++
Raw Normal View History

2012-01-21 21:57:41 +01:00
#include "gui.hpp"
#include <algorithm>
template <class T> static inline T loopNum(T i, T s)
{
return (i + s) % s;
}
TexData CButtonsMgr::_noTexture;
2012-01-21 21:57:41 +01:00
CButtonsMgr m_btnMgr;
bool CButtonsMgr::init()
2012-01-21 21:57:41 +01:00
{
m_elts.clear();
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
{
m_selected[chan] = -1;
m_rumble[chan] = 0;
}
m_rumbleEnabled = false;
m_soundVolume = 0xFF;
m_noclick = false;
m_nohover = false;
m_mouse = false;
2012-01-21 21:57:41 +01:00
soundInit();
return true;
}
s16 CButtonsMgr::addButton(SFont font, const wstringEx &text, int x, int y, u32 width, u32 height, const CColor &color,
const SButtonTextureSet &texSet, GuiSound *clickSound, GuiSound *hoverSound)
2012-01-21 21:57:41 +01:00
{
SButton *b = new SButton;
2012-01-21 21:57:41 +01:00
b->font = font;
b->visible = false;
b->text.setText(b->font, text);
2012-01-21 21:57:41 +01:00
b->textColor = color;
b->x = x + width / 2;
b->y = y + height / 2;
b->w = width;
b->h = height;
b->alpha = 0;
b->targetAlpha = 0;
b->scaleX = 0.f;
b->scaleY = 0.f;
b->targetScaleX = 0.f;
b->targetScaleY = 0.f;
b->click = 0.f;
b->tex = texSet;
b->clickSound = clickSound;
b->hoverSound = hoverSound;
b->moveByX = 0;
b->moveByY = 0;
u16 sz = m_elts.size();
m_elts.push_back(b);
2012-01-21 21:57:41 +01:00
return m_elts.size() > sz ? m_elts.size() - 1 : -2;
}
s16 CButtonsMgr::addPicButton(TexData &texNormal, TexData &texSelected, int x, int y, u32 width, u32 height, GuiSound *clickSound, GuiSound *hoverSound)
{
SButtonTextureSet texSet;
texSet.center = texNormal;
texSet.centerSel = texSelected;
return addButton(SFont(), wstringEx(), x, y, width, height, CColor(), texSet, clickSound, hoverSound);
}
s16 CButtonsMgr::addPicButton(const u8 *pngNormal, const u8 *pngSelected, int x, int y, u32 width, u32 height, GuiSound *clickSound, GuiSound *hoverSound)
{
SButtonTextureSet texSet;
TexHandle.fromPNG(texSet.center, pngNormal);
TexHandle.fromPNG(texSet.centerSel, pngSelected);
return addButton(SFont(), wstringEx(), x, y, width, height, CColor(), texSet, clickSound, hoverSound);
}
s16 CButtonsMgr::addLabel(SFont font, const wstringEx &text, int x, int y, u32 width, u32 height, const CColor &color, s16 style, const TexData &bg)
{
SLabel *b = new SLabel;
b->font = font;
b->visible = false;
b->textStyle = style;
b->text.setText(b->font, text);
b->text.setFrame(width, b->textStyle, false, true);
b->textColor = color;
b->x = x + width / 2;
b->y = y + height / 2;
b->w = width;
b->h = height;
b->alpha = 0;
b->targetAlpha = 0;
b->scaleX = 0.f;
b->scaleY = 0.f;
b->targetScaleX = 0.f;
b->targetScaleY = 0.f;
b->texBg = bg;
b->moveByX = 0;
b->moveByY = 0;
u32 sz = m_elts.size();
m_elts.push_back(b);
return m_elts.size() > sz ? m_elts.size() - 1 : -2;
}
s16 CButtonsMgr::addProgressBar(int x, int y, u32 width, u32 height, SButtonTextureSet &texSet)
{
SProgressBar *b = new SProgressBar;
b->visible = false;
b->x = x + width / 2;
b->y = y + height / 2;
b->w = width;
b->h = height;
b->alpha = 0;
b->targetAlpha = 0;
b->scaleX = 0.f;
b->scaleY = 0.f;
b->targetScaleX = 0.f;
b->targetScaleY = 0.f;
b->tex = texSet;
b->val = 0.f;
b->targetVal = 0.f;
b->moveByX = 0;
b->moveByY = 0;
u32 sz = m_elts.size();
m_elts.push_back(b);
return m_elts.size() > sz ? m_elts.size() - 1 : -2;
}
void CButtonsMgr::setText(s16 id, const wstringEx &text, bool unwrap)// unwrap means no wrap
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SLabel *lbl = NULL;
SButton *btn = NULL;
switch (m_elts[id]->t)
{
case GUIELT_BUTTON:
btn = (SButton*)m_elts[id];
btn->text.setText(btn->font, text);
break;
case GUIELT_LABEL:
lbl = (SLabel*)m_elts[id];
lbl->text.setText(lbl->font, text);
if (unwrap)
lbl->text.setFrame(100000, lbl->textStyle, true, true);
else
lbl->text.setFrame(lbl->w, lbl->textStyle, false, !unwrap);
break;
case GUIELT_PROGRESS:
break;
}
}
}
void CButtonsMgr::setText(s16 id, const wstringEx &text, u32 startline, bool unwrap)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SButton *btn = NULL;
SLabel *lbl = NULL;
switch(m_elts[id]->t)
{
case GUIELT_BUTTON:
btn = (SButton*)m_elts[id];
btn->text.setText(btn->font, text);
break;
case GUIELT_LABEL:
lbl = (SLabel*)m_elts[id];
lbl->text.setText(lbl->font, text, startline);
if (unwrap)
lbl->text.setFrame(100000, lbl->textStyle, true, true);
else
lbl->text.setFrame(lbl->w, lbl->textStyle, false, !unwrap);
break;
case GUIELT_PROGRESS:
break;
}
}
}
void CButtonsMgr::setBtnTexture(s16 id, TexData &texNormal, TexData &texSelected)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SButton *b = (SButton*)m_elts[id];
/* free old textures */
TexHandle.Cleanup(b->tex.center);
TexHandle.Cleanup(b->tex.centerSel);
/*change textures */
b->tex.center = texNormal;
b->tex.centerSel = texSelected;
}
}
void CButtonsMgr::freeBtnTexture(s16 id)
{
if(id == -1) return;
if(id < (s32)m_elts.size())
{
SButton *b = (SButton*)m_elts[id];
TexHandle.Cleanup(b->tex.center);
TexHandle.Cleanup(b->tex.centerSel);
}
}
void CButtonsMgr::setTexture(s16 id, TexData &bg)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SLabel *lbl = NULL;
switch(m_elts[id]->t)
{
case GUIELT_BUTTON:
break;
case GUIELT_LABEL:
lbl = (SLabel*)m_elts[id];
lbl->texBg = bg;//change texture
break;
case GUIELT_PROGRESS:
break;
}
}
}
void CButtonsMgr::setTexture(s16 id, TexData &bg, int width, int height)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SLabel *lbl = NULL;
switch(m_elts[id]->t)
{
case GUIELT_BUTTON:
break;
case GUIELT_LABEL:
lbl = (SLabel*)m_elts[id];
lbl->texBg = bg;//change texture
/* x and y are currently the center of the w and h plus x and y */
/* we need to set x and y back to upper left corner */
lbl->x = lbl->x - lbl->w / 2;
lbl->y = lbl->y - lbl->h / 2;
lbl->w = width;
lbl->h = height;
lbl->x = lbl->x + width / 2;// set to new center based on new w and h
lbl->y = lbl->y + height / 2;
lbl->targetPos = Vector3D((float)(lbl->x + lbl->hideParam.dx), (float)(lbl->y + lbl->hideParam.dy), 0.f);
lbl->pos = lbl->targetPos;
break;
case GUIELT_PROGRESS:
break;
}
}
}
void CButtonsMgr::setTexture(s16 id, TexData &bg, int x_pos, int y_pos, int width, int height)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SLabel *lbl = NULL;
switch(m_elts[id]->t)
{
case GUIELT_BUTTON:
break;
case GUIELT_LABEL:
lbl = (SLabel*)m_elts[id];
lbl->texBg = bg;//change texture
lbl->w = width;
lbl->h = height;
lbl->x = x_pos + width / 2;
lbl->y = y_pos + height / 2;
lbl->targetPos = Vector3D((float)(lbl->x + lbl->hideParam.dx), (float)(lbl->y + lbl->hideParam.dy), 0.f);
lbl->pos = lbl->targetPos;
break;
case GUIELT_PROGRESS:
break;
}
}
}
void CButtonsMgr::setProgress(s16 id, float f, bool instant)
{
if(m_elts[id]->t == GUIELT_PROGRESS)
{
SProgressBar *b = (SProgressBar*)m_elts[id];
b->targetVal = std::min(std::max(0.f, f), 1.f);
if (instant) b->val = b->targetVal;
}
}
void CButtonsMgr::reset(s16 id, bool instant)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
SElement &b = *m_elts[id];
2012-01-21 21:57:41 +01:00
b.x -= b.moveByX;
b.y -= b.moveByY;
if (instant)
{
b.pos.x -= b.moveByX;
b.pos.y -= b.moveByY;
}
b.targetPos.x -= b.moveByX;
b.targetPos.y -= b.moveByY;
b.moveByX = 0;
b.moveByY = 0;
}
}
void CButtonsMgr::moveBy(s16 id, int x, int y, bool instant)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
CButtonsMgr::SElement &b = *m_elts[id];
b.moveByX += x;
b.moveByY += y;
b.x += x;
b.y += y;
if (instant)
{
b.pos.x += x;
b.pos.y += y;
}
b.targetPos.x += x;
b.targetPos.y += y;
}
}
-updating wiiflow lite to beta 4.3.0 -fixed using categories to hide GC disc 2's. Apparently this has never really worked right for some time or ever. -fixed deleting the cached cover texture file for plugin games. Delete cover for plugins only deletes the cached texture file (.wfc) -fixed favorites and adultonly (parental lock) for plugin games. Apparently I may have broke this a few revisions back. -favorites and adultonly for plugin games now have their own domains in gamecfg1- [FAVORITES_PLUGINS] and [ADULTONLY_PLUGINS]. just makes it more organized. -only wii, GC, channels are added to [PLAYCOUNT] and [LAST_PLAYED] in gamecfg1. -now loading gamecfg1 at startup and leaving it loaded till exit. no more loading it and unloading all the time. -fixed scrolling for game_info synopsis, credits, and help text. -made source menu buttons wider for wiiflow default. old 80x80, now 100x80. looks better. -display music info now defaults to off -screensaver_disabled now defaults to yes -show GC view button is now on by default no matter what. the only way it is disabled is if you edit wiiflow.ini manually. this is how all the view buttons work. -removed hiding homebrew button but if wiiflow locked it won't work or in sourceflow it won't show. -dump_list is now under [GENERAL] instead of each view. Also only works for Wii, GC, and channels. -sorting only works for Wii, GC, and Channels now. disabled for sourceflow, plugins, homebrew, and combined view. -now if no games are found a message is shown with the current path so you can see where wiiflow is looking. (except for plugins) -removed auto create emuNAND for emuNAND view if gamelist is empty. just go to settings>NAND settings if you want to extract or disable it. -now when no games are found all buttons at bottom are still accessible allowing you to change the view or go to settings and change current partition or path and even extract your NAND to create a EmuNAND. Or go to Home Menu and Install a Wii or GC game. -removed auto extract NAND to emuNAND when launching a Wii game with EmuNAND save. Now a message is diplayed saying 'emuNAND for saves not found - using real NAND'. -made the speed at which cover titles fade in/out almost instantly. -removed update button from Home Menu. online update code is still there but not used and probably won't be used any more as there just isn't a need for it now. -removed ftp button from Home Menu and all code for the FTP server. I just use WiiXplorer's FTP server. it seems to work better for me. -disabled keep USB Alive thread for now. i think there's a possibilty it might be the cause of my SD/USB files getting corrupted. -removed Btn B and - combo to switch partitions. didn't seem useful anymore. -redid nand emulation settings menu. looks like this now: pg1 Select EmuNAND EmuNAND Enulation Select SaveNAND SaveNAND Emulation pg2 Extract Saves All Missing Extract NAND Select Saves Partition -no longer blocking Select Plugin menu and View icons when using source menu combined view -now Select Plugins Menu is like switching to plugin view but you get to choose the plugins first -now [PLUGIN] partition= is the default partition for all plugins. to change individual plugins add 'romPartition=x' to the plugin ini. x is the partition number 0 thru 8 with SD being 0. this is how my usbloadergx plugin mod works.
2016-10-05 01:44:13 +02:00
void CButtonsMgr::getTotalHeight(s16 id, int &height)
{
if (id == -1) return;
if (id < (s32)m_elts.size())
{
SLabel *s = (SLabel*)m_elts[id];
height = s->text.getTotalHeight();
}
}
void CButtonsMgr::getDimensions(s16 id, int &x, int &y, u32 &width, u32 &height)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
CButtonsMgr::SElement &b = *m_elts[id];
x = b.targetPos.x;
y = b.targetPos.y;
width = b.w;
height = b.h;
if(b.t == GUIELT_LABEL)
2012-01-21 21:57:41 +01:00
{
SLabel *s = (SLabel*)m_elts[id];
2012-01-21 21:57:41 +01:00
// Calculate height
height = s->text.getTotalHeight();
}
}
}
void CButtonsMgr::hide(s16 id, int dx, int dy, float scaleX, float scaleY, bool instant)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
SElement &b = *m_elts[id];
2012-01-21 21:57:41 +01:00
b.hideParam.dx = dx;
b.hideParam.dy = dy;
b.hideParam.scaleX = scaleX;
b.hideParam.scaleY = scaleY;
b.visible = false;
b.targetScaleX = scaleX;
b.targetScaleY = scaleY;
b.targetPos = Vector3D((float)(b.x + dx), (float)(b.y + dy), 0.f);
b.targetAlpha = 0x00;
if (instant)
{
b.scaleX = b.targetScaleX;
b.scaleY = b.targetScaleY;
b.pos = b.targetPos;
b.alpha = b.targetAlpha;
}
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
if (m_selected[chan] == id)
m_selected[chan] = -1;
}
}
void CButtonsMgr::hide(s16 id, bool instant)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
CButtonsMgr::SElement &b = *m_elts[id];
hide(id, b.hideParam.dx, b.hideParam.dy, b.hideParam.scaleX, b.hideParam.scaleY, instant);
}
}
void CButtonsMgr::show(s16 id, bool instant)
2012-01-21 21:57:41 +01:00
{
if (id == -1) return;
if (id < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
SElement &b = *m_elts[id];
2012-01-21 21:57:41 +01:00
b.visible = true;
b.targetScaleX = 1.0f;
b.targetScaleY = 1.0f;
b.targetPos = Vector3D((float)b.x, (float)b.y, 0);
b.targetAlpha = 0xFF;
if (instant)
{
b.scaleX = b.targetScaleX;
b.scaleY = b.targetScaleY;
b.pos = b.targetPos;
b.alpha = b.targetAlpha;
}
}
}
void CButtonsMgr::stopSounds(void)
{
for (u32 i = 0; i < m_elts.size(); ++i)
if (m_elts[i]->t == GUIELT_BUTTON)
{
SButton *b = (SButton*)m_elts[i];
b->hoverSound->Stop();
b->clickSound->Stop();
}
}
void CButtonsMgr::setSoundVolume(int vol)
{
m_soundVolume = std::min(std::max(0, vol), 0xFF);
}
void CButtonsMgr::setRumble(int chan, bool wii, bool gc, bool wupc)
2012-01-21 21:57:41 +01:00
{
wii_rumble[chan] = wii;
gc_rumble[chan] = gc;
wupc_rumble[chan] = wupc;
2012-01-21 21:57:41 +01:00
}
void CButtonsMgr::setMouse(bool enable)
2012-01-21 21:57:41 +01:00
{
m_mouse = enable;
}
2012-01-21 21:57:41 +01:00
void CButtonsMgr::noHover(bool nohover)
{
m_nohover = nohover;
}
void CButtonsMgr::noClick(bool noclick)
{
m_noclick = noclick;
}
// **********************************************************************************************
// * This makes the click sound when a button is selected unless m_noclick is true. *
// * You check to see if a controller button pressed and then call m_btnMgr.selected(btn name) *
// **********************************************************************************************
bool CButtonsMgr::selected(s16 button)
{
for(int chan = WPAD_MAX_WIIMOTES - 1; chan >= 0; chan--)
{
if(m_selected[chan] == button)
{
if(m_selected[chan] != -1 && !m_noclick)
click(m_selected[chan]);
return true;
}
}
return false;
}
void CButtonsMgr::setSelected(s16 button)
{
SElement &b = *m_elts[button];
m_selected[0] = button;
b.targetScaleX = 1.1f;
b.targetScaleY = 1.1f;
}
// **********************************************************************************************
// * Plays the click sound for the function above. Also sets rumble off and enlarges button *
// **********************************************************************************************
void CButtonsMgr::click(s16 id)
{
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
{
WUPC_Rumble(chan, 0);
WPAD_Rumble(chan, 0);
PAD_ControlMotor(chan, 0);
if (id == -1) id = m_selected[chan];
if (id == -1) continue;
if (id < (s32)m_elts.size() && m_elts[id]->t == GUIELT_BUTTON)
{
SButton *b = (SButton*)m_elts[id];
b->click = 1.f;
b->scaleX = 1.1f;
b->scaleY = 1.1f;
if (m_soundVolume > 0) b->clickSound->Play(m_soundVolume);
}
}
}
// ********************************************************************************************
// * This is for using the mouse/pointer to select a button. It slightly enlarges the button, *
// * makes the hover sound if it's newly selected and if m_noHover is not set, and uses *
// * rumble if set on. *
// ********************************************************************************************
void CButtonsMgr::mouse(int chan, int x, int y)
{
if (m_elts.empty()) return;
float w, h;
s32 start = -1;
if(m_selected[chan] != -1 && m_selected[chan] < (s32)m_elts.size())
{
m_elts[m_selected[chan]]->targetScaleX = 1.f;
m_elts[m_selected[chan]]->targetScaleY = 1.f;
start = m_selected[chan];
}
m_selected[chan] = -1;
for(int i = (int)m_elts.size() - 1; i >= 0; --i)
{
SElement &b = *m_elts[i];
if(b.t == GUIELT_BUTTON)
{
SButton &but = *(SButton*)&b;
2012-01-21 21:57:41 +01:00
w = (float)(but.w / 2);
h = (float)(but.h / 2);
if(but.visible && (float)x >= but.pos.x - w && (float)x < but.pos.x + w && (float)y >= but.pos.y - h && (float)y < but.pos.y + h)
2012-01-21 21:57:41 +01:00
{
m_selected[chan] = i;
but.targetScaleX = 1.05f;
but.targetScaleY = 1.05f;
//
if(start != m_selected[chan])
2012-01-21 21:57:41 +01:00
{
if(m_soundVolume > 0)
{
if(!m_nohover)
but.hoverSound->Play(m_soundVolume);
}
if(m_rumbleEnabled)
2012-01-21 21:57:41 +01:00
{
m_rumble[chan] = 4;
if(wupc_rumble[chan]) WUPC_Rumble(chan, 1);
2012-01-21 21:57:41 +01:00
if(wii_rumble[chan]) WPAD_Rumble(chan, 1);
if(gc_rumble[chan]) PAD_ControlMotor(chan, 1);
}
}
break;
}
}
}
}
// **************************************************************************************************
// * This is for moving backwards to the next available button when using the d-pad instead of the *
// * pointer/mouse. The Button is slightly enlarged to show it's been selected. *
// **************************************************************************************************
2012-01-21 21:57:41 +01:00
void CButtonsMgr::up(void)
{
if(m_elts.empty() || m_mouse)
return;
u32 start = 0;
2012-01-21 21:57:41 +01:00
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
{
if(m_selected[chan] != -1 && m_selected[chan] < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
m_elts[m_selected[chan]]->targetScaleX = 1.f;
m_elts[m_selected[chan]]->targetScaleY = 1.f;
start = m_selected[chan];
2012-01-21 21:57:41 +01:00
}
m_selected[chan] = -1;
}
for(u32 i = 1; i <= m_elts.size(); ++i)
{
u32 j = loopNum<u32>(start - i, m_elts.size());
SElement &b = *m_elts[j];
if (b.t == GUIELT_BUTTON && b.visible)
2012-01-21 21:57:41 +01:00
{
m_selected[0] = j;
b.targetScaleX = 1.1f;// mouse only enlarges 1.05
b.targetScaleY = 1.1f;
break;
2012-01-21 21:57:41 +01:00
}
}
}
// **************************************************************************************************
// * This is for moving forwards to the next available button when using the d-pad instead of the *
// * pointer/mouse. The Button is slightly enlarged to show it's been selected. *
// **************************************************************************************************
2012-01-21 21:57:41 +01:00
void CButtonsMgr::down(void)
{
if(m_elts.empty() || m_mouse)
return;
u32 start = 0;
2012-01-21 21:57:41 +01:00
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
{
if(m_selected[chan] != -1 && m_selected[chan] < (s32)m_elts.size())
2012-01-21 21:57:41 +01:00
{
m_elts[m_selected[chan]]->targetScaleX = 1.f;
m_elts[m_selected[chan]]->targetScaleY = 1.f;
start = m_selected[chan];
2012-01-21 21:57:41 +01:00
}
m_selected[chan] = -1;
}
for(u32 i = 1; i <= m_elts.size(); ++i)
{
u32 j = loopNum<u32>(start + i, m_elts.size());
SElement &b = *m_elts[j];
if (b.t == GUIELT_BUTTON && b.visible)
2012-01-21 21:57:41 +01:00
{
m_selected[0] = j;
b.targetScaleX = 1.1f;// mouse only enlarges 1.05
b.targetScaleY = 1.1f;
break;
2012-01-21 21:57:41 +01:00
}
}
}
void CButtonsMgr::tick(void)
2012-01-21 21:57:41 +01:00
{
for (u32 i = 0; i < m_elts.size(); ++i)
m_elts[i]->tick();
2012-01-21 21:57:41 +01:00
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
if (m_rumble[chan] > 0 && --m_rumble[chan] == 0)
2012-01-21 21:57:41 +01:00
{
WUPC_Rumble(chan, 0);
WPAD_Rumble(chan, 0);
PAD_ControlMotor(chan, 0);
2012-01-21 21:57:41 +01:00
}
}
void CButtonsMgr::SLabel::tick(void)
{
CButtonsMgr::SElement::tick();
text.tick();
}
void CButtonsMgr::SButton::tick(void)
{
CButtonsMgr::SElement::tick();
click += -click * 0.2f;
if (click < 0.01f) click = 0.f;
text.tick();
2012-01-21 21:57:41 +01:00
}
void CButtonsMgr::SProgressBar::tick(void)
{
CButtonsMgr::SElement::tick();
val += (targetVal - val) * 0.1f;
}
void CButtonsMgr::SElement::tick(void)
2012-01-21 21:57:41 +01:00
{
scaleX += (targetScaleX - scaleX) * (targetScaleX > scaleX ? 0.3f : 0.1f);
scaleY += (targetScaleY - scaleY) * (targetScaleY > scaleY ? 0.3f : 0.1f);
int alphaDist = (int)targetAlpha - (int)alpha;
alpha += abs(alphaDist) >= 8 ? (u8)(alphaDist / 8) : (u8)alphaDist;
pos += (targetPos - pos) * 0.1f;
2012-01-21 21:57:41 +01:00
}
void CButtonsMgr::_drawBtn(CButtonsMgr::SButton &b, bool selected, bool click)
2012-01-21 21:57:41 +01:00
{
GXTexObj texObjLeft;
GXTexObj texObjCenter;
GXTexObj texObjRight;
Mtx modelViewMtx;
u8 alpha = b.alpha;
float w, h, wh, scaleX = b.scaleX, scaleY = b.scaleY;
if (click)
{
alpha = (u8)(b.click * 255.f);
scaleX = (1.f - b.click) * 1.6f;
scaleY = (1.f - b.click) * 1.6f;
}
if (alpha == 0 || scaleX == 0.f || scaleY == 0.f) return;
guMtxIdentity(modelViewMtx);
guMtxTransApply(modelViewMtx, modelViewMtx, b.pos.x, b.pos.y, 0.f);
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
if (!!b.tex.left.data && !!b.tex.right.data && !!b.tex.leftSel.data && !!b.tex.rightSel.data && !!b.tex.center.data && !!b.tex.centerSel.data)
{
if (selected)
{
GX_InitTexObj(&texObjLeft, b.tex.leftSel.data, b.tex.leftSel.width, b.tex.leftSel.height, b.tex.leftSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjCenter, b.tex.centerSel.data, b.tex.centerSel.width, b.tex.centerSel.height, b.tex.centerSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjRight, b.tex.rightSel.data, b.tex.rightSel.width, b.tex.rightSel.height, b.tex.rightSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
}
else
{
GX_InitTexObj(&texObjLeft, b.tex.left.data, b.tex.left.width, b.tex.left.height, b.tex.left.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjCenter, b.tex.center.data, b.tex.center.width, b.tex.center.height, b.tex.center.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjRight, b.tex.right.data, b.tex.right.width, b.tex.right.height, b.tex.right.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
}
w = (float)(b.w / 2) * scaleX;
h = (float)(b.h / 2) * scaleY;
wh = (float)(b.h / 2) * scaleX;
GX_LoadTexObj(&texObjLeft, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(-w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(2.f * wh - w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(2.f * wh - w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(-w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjCenter, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(2.f * wh - w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(w - 2.f * wh, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(w - 2.f * wh, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(2.f * wh - w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjRight, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(w - 2.f * wh, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(w - 2.f * wh, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
}
else if (!!b.tex.center.data && !!b.tex.centerSel.data)
{
if (selected)
GX_InitTexObj(&texObjLeft, b.tex.centerSel.data, b.tex.centerSel.width, b.tex.centerSel.height, b.tex.centerSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
else
GX_InitTexObj(&texObjLeft, b.tex.center.data, b.tex.center.width, b.tex.center.height, b.tex.center.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
w = (float)(b.w / 2) * scaleX;
h = (float)(b.h / 2) * scaleY;
GX_LoadTexObj(&texObjLeft, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(-w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(-w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
}
if (!b.font.font) return;
b.font.font->reset();
b.font.font->setXScale(scaleX);
b.font.font->setYScale(scaleY);
b.text.setColor(CColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF)));
b.text.setFrame(b.w, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, true, true);
b.text.draw();
2012-01-21 21:57:41 +01:00
}
void CButtonsMgr::_drawLbl(CButtonsMgr::SLabel &b)
{
GXTexObj texObj;
Mtx modelViewMtx;
u8 alpha = b.alpha;
float scaleX = b.scaleX;
float scaleY = b.scaleY;
if (alpha == 0 || scaleX == 0.f || scaleY == 0.f)
return;
float w = (float)(b.w / 2) * scaleX;
float h = (float)(b.h / 2) * scaleY;
guMtxIdentity(modelViewMtx);
guMtxTransApply(modelViewMtx, modelViewMtx, b.pos.x, b.pos.y, 0.f);
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
if (b.texBg.data != NULL)
2012-01-21 21:57:41 +01:00
{
GX_InitTexObj(&texObj, b.texBg.data, b.texBg.width, b.texBg.height, b.texBg.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(-w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(-w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
}
if (!b.font.font) return;
b.font.font->reset();
b.font.font->setXScale(scaleX);
b.font.font->setYScale(scaleY);
float posX = b.pos.x;
float posY = b.pos.y;
if ((b.textStyle & FTGX_JUSTIFY_CENTER) == 0)
{
if ((b.textStyle & FTGX_JUSTIFY_RIGHT) != 0)
posX += w;
else
posX -= w;
}
if ((b.textStyle & FTGX_ALIGN_MIDDLE) == 0)
{
if ((b.textStyle & FTGX_ALIGN_BOTTOM) != 0)
posY += h;
else
posY -= h;
}
guMtxIdentity(modelViewMtx);
guMtxTransApply(modelViewMtx, modelViewMtx, posX, posY, 0.f);
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
if (b.moveByX != 0 || b.moveByY != 0)
GX_SetScissor(b.targetPos.x - b.moveByX - b.w/2, b.targetPos.y - b.moveByY - b.h/2, b.w, b.h);
2012-01-21 21:57:41 +01:00
b.text.setColor(CColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF)));
2012-01-21 21:57:41 +01:00
b.text.draw();
if (b.moveByX != 0 || b.moveByY != 0)
GX_SetScissor(0, 0, m_vid.width(), m_vid.height());
}
void CButtonsMgr::_drawPBar(const CButtonsMgr::SProgressBar &b)
{
Mtx modelMtx, modelViewMtx, viewMtx;
u8 alpha = b.alpha;
float scaleX = b.scaleX;
float scaleY = b.scaleY;
if (alpha == 0 || scaleX == 0.f || scaleY == 0.f) return;
guMtxIdentity(modelMtx);
guMtxIdentity(viewMtx);
guMtxTransApply(modelMtx, modelMtx, b.pos.x, b.pos.y, 0.f);
guMtxConcat(viewMtx, modelMtx, modelViewMtx);
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
if (!!b.tex.left.data && !!b.tex.right.data && !!b.tex.leftSel.data && !!b.tex.rightSel.data && !!b.tex.center.data && !!b.tex.centerSel.data)
{
GXTexObj texObjBg, texObjBgL, texObjBgR, texObjBar, texObjBarL, texObjBarR;
float w, h, wh, x1,x2, tx;
GX_InitTexObj(&texObjBarL, b.tex.leftSel.data, b.tex.leftSel.width, b.tex.leftSel.height, b.tex.leftSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjBar, b.tex.centerSel.data, b.tex.centerSel.width, b.tex.centerSel.height, b.tex.centerSel.format, GX_REPEAT, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjBarR, b.tex.rightSel.data, b.tex.rightSel.width, b.tex.rightSel.height, b.tex.rightSel.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjBgL, b.tex.left.data, b.tex.left.width, b.tex.left.height, b.tex.left.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjBg, b.tex.center.data, b.tex.center.width, b.tex.center.height, b.tex.center.format, GX_REPEAT, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&texObjBgR, b.tex.right.data, b.tex.right.width, b.tex.right.height, b.tex.right.format, GX_CLAMP, GX_CLAMP, GX_FALSE);
2012-01-21 21:57:41 +01:00
w = (float)(b.w / 2) * scaleX;
h = (float)(b.h / 2) * scaleY;
wh = (float)(b.h / 2) * scaleX;
x1 = 2.f * wh - w;
x2 = w - 2.f * wh;
GX_LoadTexObj(&texObjBgL, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(-w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(x1, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(x1, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(-w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjBg, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(x1, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(x2, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(x2, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(x1, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjBgR, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(x2, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(x2, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
//
x2 = x1 + (2.f * w - 4.f * wh) * b.val;
tx = (2.f * b.w - 4.f * b.h) * b.val / b.h * b.tex.centerSel.height / b.tex.centerSel.width;
GX_LoadTexObj(&texObjBarL, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(-w, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(x1, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(x1, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(-w, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjBar, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(x1, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(x2, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(tx, 0.f);
GX_Position3f32(x2, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(tx, 1.f);
GX_Position3f32(x1, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
GX_LoadTexObj(&texObjBarR, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position3f32(x2, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32(x2 + wh * 2.f, -h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 0.f);
GX_Position3f32(x2 + wh * 2.f, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(1.f, 1.f);
GX_Position3f32(x2, h, 0.f);
GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
GX_TexCoord2f32(0.f, 1.f);
GX_End();
}
}
void CButtonsMgr::draw(void)
{
if (m_elts.empty()) return;
GX_SetNumChans(1);
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetNumTexGens(1);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetAlphaUpdate(GX_TRUE);
GX_SetCullMode(GX_CULL_NONE);
GX_SetZMode(GX_DISABLE, GX_LEQUAL, GX_TRUE);
for(s32 i = 0; i < (s32)m_elts.size(); ++i)
2012-01-21 21:57:41 +01:00
{
SButton *btn = NULL;
SLabel *lbl = NULL;
SProgressBar *prg = NULL;
switch(m_elts[i]->t)
2012-01-21 21:57:41 +01:00
{
case GUIELT_BUTTON:
2012-01-21 21:57:41 +01:00
{
btn = (SButton*)m_elts[i];
2012-01-21 21:57:41 +01:00
bool drawSelected = false;
for(int chan = WPAD_MAX_WIIMOTES-1; chan >= 0; chan--)
{
if (i == m_selected[chan])
{
drawSelected = true;
break;
}
}
_drawBtn(*btn, drawSelected, false);
if (btn->click > 0.f)
_drawBtn(*btn, true, true);
2012-01-21 21:57:41 +01:00
break;
}
case GUIELT_LABEL:
2012-01-21 21:57:41 +01:00
{
lbl = (SLabel*)m_elts[i];
_drawLbl(*lbl);
2012-01-21 21:57:41 +01:00
break;
}
case CButtonsMgr::GUIELT_PROGRESS:
{
prg = (SProgressBar*)m_elts[i];
_drawPBar(*prg);
2012-01-21 21:57:41 +01:00
break;
}
}
}
}