-added flash screen image to appear before wiiflow wait animation. i hope the image isn't too big to cause problems with wfl.

-added 'noflash' arg for meta.xml if you don't want the flash screen image to appear. and no i can't make it load a image from a folder. it must be compiled in the code.
-added 'sdonly' arg for meta.xml for those of you that have everything on SD and hate the 20 second wait for wiiflow to search for usb devices. thanks einsteinx2!
-added meta.xml args support. meaning when a homebrew boot.dol or elf is launched the meta.xml (if exist) will be read for arguments and those args sent when the app is launched. this fixes the issue of custom wait images when changing themes.
-added spanish translation file 'spanish.ini'. thanks to ravmn for sending it to me!
-other minor changes, mainly remarks added for myself.
This commit is contained in:
fledge68 2018-06-27 12:47:03 +00:00
parent 1e57a1c9e6
commit 4a566375e0
16 changed files with 685 additions and 463 deletions

BIN
data/images/splash.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 3.3 MiB

View File

@ -42,9 +42,10 @@ DeviceHandler DeviceHandle;
void DeviceHandler::Init() void DeviceHandler::Init()
{ {
/* PartitionHandle inits */
sd.Init(); sd.Init();
usb.Init(); usb.Init();
OGC_Device.Init(); OGC_Device.Init();// used for Devolution gamecube iso launcher
} }
void DeviceHandler::MountAll() void DeviceHandler::MountAll()

View File

@ -356,9 +356,16 @@ void CCoverFlow::setRange(u32 rows, u32 columns)
if (m_covers != NULL) if (m_covers != NULL)
{ {
stopCoverLoader(); stopCoverLoader();
MEM2_free(m_covers);
CCover *tmpCovers = (CCover*)MEM2_alloc(sizeof(CCover) * range); CCover *tmpCovers = (CCover*)MEM2_alloc(sizeof(CCover) * range);
for(size_t i = 0; i < range; ++i) for(size_t i = 0; i < range; ++i)
tmpCovers[i] = *(new(tmpCovers+i) CCover); {
// does not allocate memory -- calls: operator new (sizeof(CCover), tmpCovers+i)
// only constructs an object at tmpCovers+i
// delete is not needed
// this is the same as CCover tmpCovers[range] except the objects memory address is specified and won't go out of scope
tmpCovers[i] = *(new (tmpCovers+i) CCover);
}
if (rows >= 3) if (rows >= 3)
for (u32 x = 0; x < columns; ++x) for (u32 x = 0; x < columns; ++x)
for (u32 y = 1; y < rows - 1; ++y) for (u32 y = 1; y < rows - 1; ++y)
@ -369,7 +376,6 @@ void CCoverFlow::setRange(u32 rows, u32 columns)
m_rows = rows; m_rows = rows;
m_columns = columns; m_columns = columns;
m_range = range; m_range = range;
MEM2_free(m_covers);
m_covers = tmpCovers; m_covers = tmpCovers;
_loadAllCovers(m_covers[m_range / 2].index); _loadAllCovers(m_covers[m_range / 2].index);
_updateAllTargets(); _updateAllTargets();
@ -1903,7 +1909,7 @@ bool CCoverFlow::start(const string &m_imgsDir)
m_covers = NULL; m_covers = NULL;
if(m_range > 0) if(m_range > 0)
{ {
m_covers = (CCover*)MEM2_alloc(sizeof(struct CCover) * m_range); m_covers = (CCover*)MEM2_alloc(sizeof(CCover) * m_range);
for(size_t i = 0; i < m_range; ++i) for(size_t i = 0; i < m_range; ++i)
m_covers[i] = *(new(m_covers+i) CCover); m_covers[i] = *(new(m_covers+i) CCover);
} }

View File

@ -748,6 +748,8 @@ void CButtonsMgr::_drawBtn(CButtonsMgr::SButton &b, bool selected, bool click)
if (!b.font.font) return; if (!b.font.font) return;
b.font.font->reset(); b.font.font->reset();
//CColor txtColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF)); //CColor txtColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF));
if(m_vid.wide())
scaleX *= 0.8f;
b.font.font->setXScale(scaleX); b.font.font->setXScale(scaleX);
b.font.font->setYScale(scaleY); b.font.font->setYScale(scaleY);
//b.font.font->drawText(0, 0, b.text.c_str(), txtColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE); //b.font.font->drawText(0, 0, b.text.c_str(), txtColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE);
@ -795,6 +797,8 @@ void CButtonsMgr::_drawLbl(CButtonsMgr::SLabel &b)
b.font.font->reset(); b.font.font->reset();
b.text.setColor(CColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF))); b.text.setColor(CColor(b.textColor.r, b.textColor.g, b.textColor.b, (u8)((int)b.textColor.a * (int)alpha / 0xFF)));
if(m_vid.wide())
scaleX *= 0.8f;
b.font.font->setXScale(scaleX); b.font.font->setXScale(scaleX);
b.font.font->setYScale(scaleY); b.font.font->setYScale(scaleY);
float posX = b.pos.x; float posX = b.pos.x;

View File

@ -3,6 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include <malloc.h> #include <malloc.h>
#include <ogc/machine/processor.h> #include <ogc/machine/processor.h>
#include <algorithm>
#include "memory/mem2.hpp" #include "memory/mem2.hpp"
#include "video.hpp" #include "video.hpp"
#include "pngu.h" #include "pngu.h"
@ -17,25 +18,6 @@
#define DEFAULT_FIFO_SIZE (256 * 1024) #define DEFAULT_FIFO_SIZE (256 * 1024)
extern const u8 wait_01_jpg[];
extern const u32 wait_01_jpg_size;
extern const u8 wait_02_jpg[];
extern const u32 wait_02_jpg_size;
extern const u8 wait_03_jpg[];
extern const u32 wait_03_jpg_size;
extern const u8 wait_04_jpg[];
extern const u32 wait_04_jpg_size;
extern const u8 wait_05_jpg[];
extern const u32 wait_05_jpg_size;
extern const u8 wait_06_jpg[];
extern const u32 wait_06_jpg_size;
extern const u8 wait_07_jpg[];
extern const u32 wait_07_jpg_size;
extern const u8 wait_08_jpg[];
extern const u32 wait_08_jpg_size;
vector<TexData> m_defaultWaitMessages;
const float CVideo::_jitter2[2][2] = { const float CVideo::_jitter2[2][2] = {
{ 0.246490f, 0.249999f }, { 0.246490f, 0.249999f },
{ -0.246490f, -0.249999f } { -0.246490f, -0.249999f }
@ -115,20 +97,10 @@ GXRModeObj TVPal574IntDfScale =
} }
}; };
struct movieP normalMoviePos = { 410, 31, 610, 181 }; vector<TexData> m_defaultWaitMessages;
struct movieP zoomedMoviePos = { 0, 0, 640, 480 };
struct movieP currentMoviePos = zoomedMoviePos;
const int CVideo::_stencilWidth = 128;
const int CVideo::_stencilHeight = 128;
static lwp_t waitThread = LWP_THREAD_NULL;
CVideo m_vid; CVideo m_vid;
u8 CVideo::waitMessageStack[2048] ATTRIBUTE_ALIGN(32);
const u32 CVideo::waitMessageStackSize = 2048;
CVideo::CVideo(void) : CVideo::CVideo(void) :
m_rmode(NULL), m_frameBuf(), m_curFB(0), m_fifo(NULL), m_rmode(NULL), m_frameBuf(), m_curFB(0), m_fifo(NULL),
m_yScale(0.0f), m_xfbHeight(0), m_wide(false), m_yScale(0.0f), m_xfbHeight(0), m_wide(false),
@ -139,35 +111,6 @@ CVideo::CVideo(void) :
memset(m_frameBuf, 0, sizeof m_frameBuf); memset(m_frameBuf, 0, sizeof m_frameBuf);
} }
void CColor::blend(const CColor &src)
{
if (src.a == 0) return;
r = (u8)(((int)src.r * (int)src.a + (int)r * (0xFF - (int)src.a)) / 0xFF);
g = (u8)(((int)src.g * (int)src.a + (int)g * (0xFF - (int)src.a)) / 0xFF);
b = (u8)(((int)src.b * (int)src.a + (int)b * (0xFF - (int)src.a)) / 0xFF);
}
CColor CColor::interpolate(const CColor &c1, const CColor &c2, u8 n)
{
CColor c;
c.r = (u8)(((int)c2.r * (int)n + (int)c1.r * (0xFF - (int)n)) / 0xFF);
c.g = (u8)(((int)c2.g * (int)n + (int)c1.g * (0xFF - (int)n)) / 0xFF);
c.b = (u8)(((int)c2.b * (int)n + (int)c1.b * (0xFF - (int)n)) / 0xFF);
c.a = (u8)(((int)c2.a * (int)n + (int)c1.a * (0xFF - (int)n)) / 0xFF);
return c;
}
void CVideo::setAA(u8 aa, bool alpha, int width, int height)
{
if (aa <= 8 && aa != 7 && width <= m_rmode->fbWidth && height <= m_rmode->efbHeight && ((width | height) & 3) == 0)
{
m_aa = aa;
m_aaAlpha = alpha;
m_aaWidth = width;
m_aaHeight = height;
}
}
void CVideo::init(void) void CVideo::init(void)
{ {
/* General Video Init */ /* General Video Init */
@ -212,11 +155,15 @@ void CVideo::init(void)
m_frameBuf[0] = MEM_K0_TO_K1(MEM1_memalign(32, VIDEO_GetFrameBufferSize(m_rmode))); m_frameBuf[0] = MEM_K0_TO_K1(MEM1_memalign(32, VIDEO_GetFrameBufferSize(m_rmode)));
m_frameBuf[1] = MEM_K0_TO_K1(MEM1_memalign(32, VIDEO_GetFrameBufferSize(m_rmode))); m_frameBuf[1] = MEM_K0_TO_K1(MEM1_memalign(32, VIDEO_GetFrameBufferSize(m_rmode)));
m_curFB = 0; m_curFB = 0;
m_fifo = MEM1_memalign(32, DEFAULT_FIFO_SIZE); m_fifo = MEM1_memalign(32, DEFAULT_FIFO_SIZE);
memset(m_fifo, 0, DEFAULT_FIFO_SIZE); memset(m_fifo, 0, DEFAULT_FIFO_SIZE);
GX_Init(m_fifo, DEFAULT_FIFO_SIZE); GX_Init(m_fifo, DEFAULT_FIFO_SIZE);
GX_SetCopyClear(CColor(0), 0x00FFFFFF); GX_SetCopyClear(CColor(0), 0x00FFFFFF);
_setViewPort(0, 0, m_rmode->fbWidth, m_rmode->efbHeight); _setViewPort(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
m_yScale = GX_GetYScaleFactor(m_rmode->efbHeight, m_rmode->xfbHeight); m_yScale = GX_GetYScaleFactor(m_rmode->efbHeight, m_rmode->xfbHeight);
m_xfbHeight = GX_SetDispCopyYScale(m_yScale); m_xfbHeight = GX_SetDispCopyYScale(m_yScale);
GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight); GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
@ -237,11 +184,14 @@ void CVideo::init(void)
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GX_SetNumChans(0); GX_SetNumChans(0);
GX_SetZCompLoc(GX_ENABLE); GX_SetZCompLoc(GX_ENABLE);
setup2DProjection(); setup2DProjection();
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
for(u32 i = 0; i < 8; i++) for(u32 i = 0; i < 8; i++)
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0+i, GX_TEX_ST, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0+i, GX_TEX_ST, GX_F32, 0);
m_stencil = MEM1_memalign(32, CVideo::_stencilWidth * CVideo::_stencilHeight); m_stencil = MEM1_memalign(32, CVideo::_stencilWidth * CVideo::_stencilHeight);
memset(m_stencil, 0, CVideo::_stencilWidth * CVideo::_stencilHeight); memset(m_stencil, 0, CVideo::_stencilWidth * CVideo::_stencilHeight);
@ -255,65 +205,6 @@ void CVideo::init(void)
VIDEO_WaitVSync(); VIDEO_WaitVSync();
} }
void CVideo::_clearScreen()
{
VIDEO_ClearFrameBuffer(m_rmode, m_frameBuf[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(m_rmode, m_frameBuf[1], COLOR_BLACK);
render();
render();
}
void CVideo::set2DViewport(u32 w, u32 h, int x, int y)
{
m_width2D = std::min(std::max(512ul, w), 800ul);
m_height2D = std::min(std::max(384ul, h), 600ul);
m_x2D = std::min(std::max(-50, x), 50);
m_y2D = std::min(std::max(-50, y), 50);
}
void CVideo::setup2DProjection(bool setViewPort, bool noScale)
{
Mtx44 projMtx;
float width2D = noScale ? 640.f : (float)m_width2D;
float height2D = noScale ? 480.f : (float)m_height2D;
float x = noScale ? 0.f : (float)(640 - width2D) * 0.5f + (float)m_x2D;
float y = noScale ? 0.f : (float)(480 - height2D) * 0.5f + (float)m_y2D;
if (setViewPort)
_setViewPort(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
guOrtho(projMtx, y, height2D + y, x, width2D + x, 0.f, 1000.0f);
GX_LoadProjectionMtx(projMtx, GX_ORTHOGRAPHIC);
}
void CVideo::renderToTexture(TexData &tex, bool clear)
{
if(tex.data == NULL)
{
tex.dataSize = GX_GetTexBufferSize(tex.width, tex.height, tex.format, GX_FALSE, 0);
tex.data = (u8*)MEM2_alloc(tex.dataSize);
if(tex.data == NULL)
return;
}
GX_DrawDone();
GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
GX_SetTexCopySrc(0, 0, tex.width, tex.height);
GX_SetTexCopyDst(tex.width, tex.height, tex.format, GX_FALSE);
GX_CopyTex(tex.data, clear ? GX_TRUE : GX_FALSE);
GX_PixModeSync();
GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter);
DCFlushRange(tex.data, tex.dataSize);
GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
}
void CVideo::prepare(void)
{
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
_setViewPort(0.f, 0.f, (float)m_rmode->fbWidth, (float)m_rmode->efbHeight);
GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
GX_InvVtxCache();
GX_InvalidateTexAll();
}
void CVideo::cleanup(void) void CVideo::cleanup(void)
{ {
//gprintf("Cleaning up video...\n"); //gprintf("Cleaning up video...\n");
@ -350,6 +241,79 @@ void CVideo::cleanup(void)
m_fifo = NULL; m_fifo = NULL;
} }
void CVideo::_clearScreen()
{
VIDEO_ClearFrameBuffer(m_rmode, m_frameBuf[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(m_rmode, m_frameBuf[1], COLOR_BLACK);
render();
render();
}
void CVideo::prepare(void)
{
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
_setViewPort(0.f, 0.f, (float)m_rmode->fbWidth, (float)m_rmode->efbHeight);
GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
GX_InvVtxCache();
GX_InvalidateTexAll();
}
void CVideo::setup2DProjection(bool setViewPort, bool noScale)
{
Mtx44 projMtx;
float width2D = noScale ? 640.f : (float)m_width2D;
float height2D = noScale ? 480.f : (float)m_height2D;
float x = noScale ? 0.f : (float)(640 - width2D) * 0.5f + (float)m_x2D;
float y = noScale ? 0.f : (float)(480 - height2D) * 0.5f + (float)m_y2D;
if (setViewPort)
_setViewPort(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
guOrtho(projMtx, y, height2D + y, x, width2D + x, 0.f, 1000.0f);
GX_LoadProjectionMtx(projMtx, GX_ORTHOGRAPHIC);
}
void CVideo::_setViewPort(float x, float y, float w, float h)
{
m_vpX = x;
m_vpY = y;
m_vpW = w;
m_vpH = h;
GX_SetViewport(x, y, w, h, 0.f, 1.f);
}
void CVideo::shiftViewPort(float x, float y)
{
GX_SetViewport(m_vpX + x, m_vpY + y, m_vpW, m_vpH, 0.f, 1.f);
}
void CVideo::set2DViewport(u32 w, u32 h, int x, int y)
{
m_width2D = std::min(std::max(512ul, w), 800ul);
m_height2D = std::min(std::max(384ul, h), 600ul);
m_x2D = std::min(std::max(-50, x), 50);
m_y2D = std::min(std::max(-50, y), 50);
}
void CVideo::renderToTexture(TexData &tex, bool clear)
{
if(tex.data == NULL)
{
tex.dataSize = GX_GetTexBufferSize(tex.width, tex.height, tex.format, GX_FALSE, 0);
tex.data = (u8*)MEM2_alloc(tex.dataSize);
if(tex.data == NULL)
return;
}
GX_DrawDone();
GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
GX_SetTexCopySrc(0, 0, tex.width, tex.height);
GX_SetTexCopyDst(tex.width, tex.height, tex.format, GX_FALSE);
GX_CopyTex(tex.data, clear ? GX_TRUE : GX_FALSE);
GX_PixModeSync();
GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter);
DCFlushRange(tex.data, tex.dataSize);
GX_SetScissor(0, 0, m_rmode->fbWidth, m_rmode->efbHeight);
}
void CVideo::prepareAAPass(int aaStep) void CVideo::prepareAAPass(int aaStep)
{ {
float x = 0.f; float x = 0.f;
@ -390,31 +354,6 @@ void CVideo::prepareAAPass(int aaStep)
GX_InvalidateTexAll(); GX_InvalidateTexAll();
} }
void CVideo::renderAAPass(int aaStep)
{
u8 texFmt = GX_TF_RGBA8;
u32 w = m_aaWidth <= 0 ? m_rmode->fbWidth : (u32)m_aaWidth;
u32 h = m_aaHeight <= 0 ? m_rmode->efbHeight: (u32)m_aaHeight;
u32 bufLen = GX_GetTexBufferSize(w, h, texFmt, GX_FALSE, 0);
if (!m_aaBuffer[aaStep] || m_aaBufferSize[aaStep] < bufLen)
{
m_aaBuffer[aaStep] = (u8*)MEM2_alloc(bufLen);
if (m_aaBuffer[aaStep] != NULL)
m_aaBufferSize[aaStep] = bufLen;
}
if (!m_aaBuffer[aaStep] || m_aaBufferSize[aaStep] < bufLen)
return;
GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_TRUE);
GX_DrawDone();
GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
GX_SetTexCopySrc(0, 0, w, h);
GX_SetTexCopyDst(w, h, texFmt, GX_FALSE);
GX_CopyTex(m_aaBuffer[aaStep], GX_TRUE);
GX_PixModeSync();
GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter);
}
void CVideo::drawAAScene(bool fs) void CVideo::drawAAScene(bool fs)
{ {
GXTexObj texObj[8]; GXTexObj texObj[8];
@ -488,57 +427,28 @@ void CVideo::drawAAScene(bool fs)
GX_SetNumTevStages(1); GX_SetNumTevStages(1);
} }
void CVideo::_setViewPort(float x, float y, float w, float h) void CVideo::renderAAPass(int aaStep)
{ {
m_vpX = x; u8 texFmt = GX_TF_RGBA8;
m_vpY = y; u32 w = m_aaWidth <= 0 ? m_rmode->fbWidth : (u32)m_aaWidth;
m_vpW = w; u32 h = m_aaHeight <= 0 ? m_rmode->efbHeight: (u32)m_aaHeight;
m_vpH = h; u32 bufLen = GX_GetTexBufferSize(w, h, texFmt, GX_FALSE, 0);
GX_SetViewport(x, y, w, h, 0.f, 1.f);
}
void CVideo::shiftViewPort(float x, float y) if (!m_aaBuffer[aaStep] || m_aaBufferSize[aaStep] < bufLen)
{ {
GX_SetViewport(m_vpX + x, m_vpY + y, m_vpW, m_vpH, 0.f, 1.f); m_aaBuffer[aaStep] = (u8*)MEM2_alloc(bufLen);
} if (m_aaBuffer[aaStep] != NULL)
m_aaBufferSize[aaStep] = bufLen;
static inline u32 coordsI8(u32 x, u32 y, u32 w) }
{ if (!m_aaBuffer[aaStep] || m_aaBufferSize[aaStep] < bufLen)
return (((y >> 2) * (w >> 3) + (x >> 3)) << 5) + ((y & 3) << 3) + (x & 7); return;
}
int CVideo::stencilVal(int x, int y)
{
if ((u32)x >= m_rmode->fbWidth || (u32)y >= m_rmode->efbHeight)
return 0;
x = x * CVideo::_stencilWidth / 640;
y = y * CVideo::_stencilHeight / 480;
u32 i = coordsI8(x, y, (u32)CVideo::_stencilWidth);
if (i >= (u32)(CVideo::_stencilWidth * CVideo::_stencilHeight))
return 0;
return ((u8*)m_stencil)[i];
}
void CVideo::prepareStencil(void)
{
GX_SetPixelFmt(GX_PF_Y8, GX_ZC_LINEAR);
_setViewPort(0.f, 0.f, (float)CVideo::_stencilWidth, (float)CVideo::_stencilHeight);
GX_SetScissor(0, 0, CVideo::_stencilWidth, CVideo::_stencilHeight);
GX_InvVtxCache();
GX_InvalidateTexAll();
}
void CVideo::renderStencil(void)
{
GX_DrawDone();
GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_TRUE); GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_TRUE);
GX_SetColorUpdate(GX_TRUE); GX_DrawDone();
GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL); GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
GX_SetTexCopySrc(0, 0, CVideo::_stencilWidth, CVideo::_stencilHeight); GX_SetTexCopySrc(0, 0, w, h);
GX_SetTexCopyDst(CVideo::_stencilWidth, CVideo::_stencilHeight, GX_CTF_R8, GX_FALSE); GX_SetTexCopyDst(w, h, texFmt, GX_FALSE);
GX_CopyTex(m_stencil, GX_TRUE); GX_CopyTex(m_aaBuffer[aaStep], GX_TRUE);
GX_PixModeSync(); GX_PixModeSync();
DCFlushRange(m_stencil, CVideo::_stencilWidth * CVideo::_stencilHeight);
GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter); GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter);
} }
@ -556,12 +466,38 @@ void CVideo::render(void)
GX_InvalidateTexAll(); GX_InvalidateTexAll();
} }
/* wait animation control */
extern const u8 splash_jpg[];
extern const u32 splash_jpg_size;
extern const u8 wait_01_jpg[];
extern const u32 wait_01_jpg_size;
extern const u8 wait_02_jpg[];
extern const u32 wait_02_jpg_size;
extern const u8 wait_03_jpg[];
extern const u32 wait_03_jpg_size;
extern const u8 wait_04_jpg[];
extern const u32 wait_04_jpg_size;
extern const u8 wait_05_jpg[];
extern const u32 wait_05_jpg_size;
extern const u8 wait_06_jpg[];
extern const u32 wait_06_jpg_size;
extern const u8 wait_07_jpg[];
extern const u32 wait_07_jpg_size;
extern const u8 wait_08_jpg[];
extern const u32 wait_08_jpg_size;
static lwp_t waitThread = LWP_THREAD_NULL;
u8 CVideo::waitMessageStack[2048] ATTRIBUTE_ALIGN(32);
const u32 CVideo::waitMessageStackSize = 2048;
bool custom = false; bool custom = false;
bool waitLoop = false; bool waitLoop = false;
static vector<string> waitImgs; static vector<string> waitImgs;
static void GrabWaitFiles(char *FullPath) static void GrabWaitFiles(char *FullPath)
{ {
//Just push back
waitImgs.push_back(FullPath); waitImgs.push_back(FullPath);
} }
@ -573,13 +509,14 @@ void CVideo::setCustomWaitImgs(const char *path, bool wait_loop)
GetFiles(path, stringToVector(".png|.jpg", '|'), GrabWaitFiles, false, 1); GetFiles(path, stringToVector(".png|.jpg", '|'), GrabWaitFiles, false, 1);
if(waitImgs.size() > 0) if(waitImgs.size() > 0)
{ {
sort(waitImgs.begin(), waitImgs.end());
custom = true; custom = true;
waitLoop = wait_loop; waitLoop = wait_loop;
} }
} }
} }
void CVideo::waitMessage(float delay)// called from main.cpp to show wait animation on wf boot void CVideo::waitMessage(float delay)// set wait images from custom or internal
{ {
if(m_defaultWaitMessages.size() == 0) if(m_defaultWaitMessages.size() == 0)
{ {
@ -613,7 +550,7 @@ void CVideo::waitMessage(float delay)// called from main.cpp to show wait animat
waitMessage(m_defaultWaitMessages, delay); waitMessage(m_defaultWaitMessages, delay);
} }
void CVideo::waitMessage(const vector<TexData> &tex, float delay)// start wait images and wii slot light threads or draw void CVideo::waitMessage(const vector<TexData> &tex, float delay)// start wait images and wii slot light threads
{ {
hideWaitMessage(); hideWaitMessage();
@ -698,7 +635,7 @@ void * CVideo::_showWaitMessages(void *obj)// wait images thread
return NULL; return NULL;
} }
void CVideo::hideWaitMessage()// stop wait images and wii disc slot light threads void CVideo::hideWaitMessage()// stop wait images thread and wii disc slot light thread
{ {
m_showWaitMessage = false; m_showWaitMessage = false;
if(waitThread != LWP_THREAD_NULL) if(waitThread != LWP_THREAD_NULL)
@ -716,7 +653,9 @@ void CVideo::hideWaitMessage()// stop wait images and wii disc slot light thread
waitThread = LWP_THREAD_NULL; waitThread = LWP_THREAD_NULL;
} }
void CVideo::waitMessage(const TexData &tex)//draw frame image /* draws wait animation image centered on screen */
/* can be used to draw any texture centered on screen */
void CVideo::waitMessage(const TexData &tex)
{ {
Mtx modelViewMtx; Mtx modelViewMtx;
GXTexObj texObj; GXTexObj texObj;
@ -743,7 +682,7 @@ void CVideo::waitMessage(const TexData &tex)//draw frame image
GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
u32 texWidth = m_wide ? tex.width * .75 : tex.width; u32 texWidth = m_wide ? tex.width * .75 : tex.width;
GX_Position3f32((float)((640 - texWidth) / 2), (float)((480 - tex.height) / 2), 0.f);// widescreen = tex.width * .80 GX_Position3f32((float)((640 - texWidth) / 2), (float)((480 - tex.height) / 2), 0.f);
GX_TexCoord2f32(0.f, 0.f); GX_TexCoord2f32(0.f, 0.f);
GX_Position3f32((float)((640 + texWidth) / 2), (float)((480 - tex.height) / 2), 0.f); GX_Position3f32((float)((640 + texWidth) / 2), (float)((480 - tex.height) / 2), 0.f);
GX_TexCoord2f32(1.f, 0.f); GX_TexCoord2f32(1.f, 0.f);
@ -754,6 +693,17 @@ void CVideo::waitMessage(const TexData &tex)//draw frame image
GX_End(); GX_End();
} }
/* draw and render startup splash screen */
void CVideo::startImage(void)
{
TexData splashTex;
TexHandle.fromJPG(splashTex, splash_jpg, splash_jpg_size);
waitMessage(splashTex);
render();
TexHandle.Cleanup(splashTex);
}
/* save screenshot */
s32 CVideo::TakeScreenshot(const char *path) s32 CVideo::TakeScreenshot(const char *path)
{ {
IMGCTX ctx = PNGU_SelectImageFromDevice(path); IMGCTX ctx = PNGU_SelectImageFromDevice(path);
@ -762,7 +712,9 @@ s32 CVideo::TakeScreenshot(const char *path)
return ret; return ret;
} }
void DrawTexture(TexData * &tex)// used by coverflow to draw cover texture. use in mainloopcommon() in menu.cpp /* used by coverflow to draw cover texture. used in mainloopcommon() in menu.cpp */
/* this draws a texture in the upper left at 0,0 */
void DrawTexture(TexData * &tex)
{ {
if(tex == NULL) if(tex == NULL)
return; return;
@ -805,35 +757,14 @@ void DrawTexture(TexData * &tex)// used by coverflow to draw cover texture. use
GX_End(); GX_End();
} }
void DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color)// used by banner window and screen saver below /* draws movie frame texture when playing movie in menu_game.cpp */
{ struct movieP normalMoviePos = { 410, 31, 610, 181 };
Mtx modelViewMtx; struct movieP zoomedMoviePos = { 0, 0, 640, 480 };
guMtxIdentity(modelViewMtx); struct movieP currentMoviePos = zoomedMoviePos;
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); /* draws a texture/image at a position and width and height specified by struct movieP currentMoviePos */
GX_ClearVtxDesc(); /* set currentMoviePos before calling this. example - {x, y, x+w, y+h} */
GX_InvVtxCache(); void DrawTexturePos(const TexData *tex)
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
int i;
f32 x2 = x + width;
f32 y2 = y + height;
guVector v[] = { { x, y, 0.0f }, { x2, y, 0.0f }, { x2, y2, 0.0f }, { x, y2, 0.0f }, { x, y, 0.0f } };
GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, 4);
for(i = 0; i < 4; i++)
{
GX_Position3f32(v[i].x, v[i].y, v[i].z);
GX_Color4u8(color.r, color.g, color.b, color.a);
}
GX_End();
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
}
void DrawTexturePos(const TexData *tex)// draws movie frame texture when playing movie in menu_game.cpp
{ {
Mtx modelViewMtx; Mtx modelViewMtx;
GXTexObj texObj; GXTexObj texObj;
@ -868,17 +799,122 @@ void DrawTexturePos(const TexData *tex)// draws movie frame texture when playing
GX_End(); GX_End();
} }
/* screen saver and full banner frame */
void DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color)
{
Mtx modelViewMtx;
guMtxIdentity(modelViewMtx);
GX_LoadPosMtxImm(modelViewMtx, GX_PNMTX0);
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
GX_ClearVtxDesc();
GX_InvVtxCache();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
int i;
f32 x2 = x + width;
f32 y2 = y + height;
guVector v[] = { { x, y, 0.0f }, { x2, y, 0.0f }, { x2, y2, 0.0f }, { x, y2, 0.0f }, { x, y, 0.0f } };
GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, 4);
for(i = 0; i < 4; i++)
{
GX_Position3f32(v[i].x, v[i].y, v[i].z);
GX_Color4u8(color.r, color.g, color.b, color.a);
}
GX_End();
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
}
void CVideo::screensaver(u32 no_input, u32 max_no_input) void CVideo::screensaver(u32 no_input, u32 max_no_input)
{ {
if(no_input == 0) if(no_input == 0)// no idle time so reset alpha to 0 for next time and don't draw the rectangle on this pass
{ {
m_screensaver_alpha = 0; m_screensaver_alpha = 0;
return; return;
} }
if(no_input > max_no_input) if(no_input > max_no_input)// if idle time > max idle draw rectangle full screen increasing alpha each time
{ {
DrawRectangle(0, 0, 640, 480, (GXColor){0,0,0,m_screensaver_alpha}); DrawRectangle(0, 0, 640, 480, (GXColor){0,0,0,m_screensaver_alpha});
if(m_screensaver_alpha < 150) if(m_screensaver_alpha < 150)
m_screensaver_alpha+=2; m_screensaver_alpha+=2;
} }
} }
/* misc settings */
void CColor::blend(const CColor &src)
{
if (src.a == 0) return;
r = (u8)(((int)src.r * (int)src.a + (int)r * (0xFF - (int)src.a)) / 0xFF);
g = (u8)(((int)src.g * (int)src.a + (int)g * (0xFF - (int)src.a)) / 0xFF);
b = (u8)(((int)src.b * (int)src.a + (int)b * (0xFF - (int)src.a)) / 0xFF);
}
CColor CColor::interpolate(const CColor &c1, const CColor &c2, u8 n)
{
CColor c;
c.r = (u8)(((int)c2.r * (int)n + (int)c1.r * (0xFF - (int)n)) / 0xFF);
c.g = (u8)(((int)c2.g * (int)n + (int)c1.g * (0xFF - (int)n)) / 0xFF);
c.b = (u8)(((int)c2.b * (int)n + (int)c1.b * (0xFF - (int)n)) / 0xFF);
c.a = (u8)(((int)c2.a * (int)n + (int)c1.a * (0xFF - (int)n)) / 0xFF);
return c;
}
void CVideo::setAA(u8 aa, bool alpha, int width, int height)
{
if (aa <= 8 && aa != 7 && width <= m_rmode->fbWidth && height <= m_rmode->efbHeight && ((width | height) & 3) == 0)
{
m_aa = aa;
m_aaAlpha = alpha;
m_aaWidth = width;
m_aaHeight = height;
}
}
/* stencil used by coverflow */
const int CVideo::_stencilWidth = 128;
const int CVideo::_stencilHeight = 128;
static inline u32 coordsI8(u32 x, u32 y, u32 w)// used by stencilval below
{
return (((y >> 2) * (w >> 3) + (x >> 3)) << 5) + ((y & 3) << 3) + (x & 7);
}
int CVideo::stencilVal(int x, int y)
{
if ((u32)x >= m_rmode->fbWidth || (u32)y >= m_rmode->efbHeight)
return 0;
x = x * CVideo::_stencilWidth / 640;
y = y * CVideo::_stencilHeight / 480;
u32 i = coordsI8(x, y, (u32)CVideo::_stencilWidth);
if (i >= (u32)(CVideo::_stencilWidth * CVideo::_stencilHeight))
return 0;
return ((u8*)m_stencil)[i];
}
void CVideo::prepareStencil(void)
{
GX_SetPixelFmt(GX_PF_Y8, GX_ZC_LINEAR);
_setViewPort(0.f, 0.f, (float)CVideo::_stencilWidth, (float)CVideo::_stencilHeight);
GX_SetScissor(0, 0, CVideo::_stencilWidth, CVideo::_stencilHeight);
GX_InvVtxCache();
GX_InvalidateTexAll();
}
void CVideo::renderStencil(void)
{
GX_DrawDone();
GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_SetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
GX_SetTexCopySrc(0, 0, CVideo::_stencilWidth, CVideo::_stencilHeight);
GX_SetTexCopyDst(CVideo::_stencilWidth, CVideo::_stencilHeight, GX_CTF_R8, GX_FALSE);
GX_CopyTex(m_stencil, GX_TRUE);
GX_PixModeSync();
DCFlushRange(m_stencil, CVideo::_stencilWidth * CVideo::_stencilHeight);
GX_SetCopyFilter(m_rmode->aa, m_rmode->sample_pattern, GX_TRUE, m_rmode->vfilter);
}

View File

@ -70,6 +70,7 @@ public:
int stencilVal(int x, int y); int stencilVal(int x, int y);
void setCustomWaitImgs(const char *path, bool loop); void setCustomWaitImgs(const char *path, bool loop);
void hideWaitMessage(); void hideWaitMessage();
void startImage(void);
void waitMessage(float delay); void waitMessage(float delay);
void waitMessage(const vector<TexData> &tex, float delay); void waitMessage(const vector<TexData> &tex, float delay);
void waitMessage(const TexData &tex); void waitMessage(const TexData &tex);

View File

@ -33,12 +33,10 @@ int main(int argc, char **argv)
Gecko_Init(); //USB Gecko and SD/WiFi buffer Gecko_Init(); //USB Gecko and SD/WiFi buffer
gprintf(" \nWelcome to %s!\nThis is the debug output.\n", VERSION_STRING.c_str()); gprintf(" \nWelcome to %s!\nThis is the debug output.\n", VERSION_STRING.c_str());
m_vid.init(); // Init video
DeviceHandle.Init();
NandHandle.Init();
char *gameid = NULL;
bool iosOK = true; bool iosOK = true;
char *gameid = NULL;
bool showFlashImg = true;
bool sd_only = false;
bool wait_loop = false; bool wait_loop = false;
char wait_dir[256]; char wait_dir[256];
memset(&wait_dir, 0, sizeof(wait_dir)); memset(&wait_dir, 0, sizeof(wait_dir));
@ -52,6 +50,17 @@ int main(int argc, char **argv)
if(atoi(argv[i]) < 254 && atoi(argv[i]) > 0) if(atoi(argv[i]) < 254 && atoi(argv[i]) > 0)
mainIOS = atoi(argv[i]); mainIOS = atoi(argv[i]);
} }
else if(strcasestr(argv[i], "waitdir=") != NULL)
{
char *ptr = strcasestr(argv[i], "waitdir=");
strncpy(wait_dir, ptr+strlen("waitdir="), sizeof(wait_dir));
}
else if(strcasestr(argv[i], "Waitloop") != NULL)
wait_loop = true;
else if(strcasestr(argv[i], "noflash") != NULL)
showFlashImg = false;
else if(strcasestr(argv[i], "sdonly") != NULL)
sd_only = true;
else if(strlen(argv[i]) == 6) else if(strlen(argv[i]) == 6)
{ {
gameid = argv[i]; gameid = argv[i];
@ -61,40 +70,51 @@ int main(int argc, char **argv)
gameid = NULL; gameid = NULL;
} }
} }
else if(strcasestr(argv[i], "waitdir=") != NULL)
{
char *ptr = strcasestr(argv[i], "waitdir=");
strncpy(wait_dir, ptr+strlen("waitdir="), sizeof(wait_dir));
}
else if(strcasestr(argv[i], "Waitloop") != NULL)
{
wait_loop = true;
}
} }
/* Init video */
m_vid.init();
if(showFlashImg)
m_vid.startImage();
/* Init device partition handlers */
DeviceHandle.Init();
/* Init NAND handlers */
NandHandle.Init();
check_neek2o(); check_neek2o();
/* Init ISFS */
if(neek2o() || Sys_DolphinMode()) if(neek2o() || Sys_DolphinMode())
NandHandle.Init_ISFS(); NandHandle.Init_ISFS();
else else
NandHandle.LoadDefaultIOS(); /* safe reload to preferred IOS */ NandHandle.LoadDefaultIOS(); /* safe reload to preferred IOS */
/* Maybe new IOS and Port settings */
/* load and check wiiflow save for possible new IOS and Port settings */
if(InternalSave.CheckSave()) if(InternalSave.CheckSave())
InternalSave.LoadSettings(); InternalSave.LoadSettings();
/* Handle (c)IOS Loading */ /* Handle (c)IOS Loading */
if(neek2o() || Sys_DolphinMode()) /* wont reload anythin */ if(neek2o() || Sys_DolphinMode()) /* wont reload anythin */
iosOK = loadIOS(IOS_GetVersion(), false); iosOK = loadIOS(IOS_GetVersion(), false);
else if(useMainIOS && CustomIOS(IOS_GetType(mainIOS))) /* Requested */ else if(useMainIOS && CustomIOS(IOS_GetType(mainIOS))) /* Requested */
iosOK = loadIOS(mainIOS, false) && CustomIOS(CurrentIOS.Type); iosOK = loadIOS(mainIOS, false) && CustomIOS(CurrentIOS.Type);
// Init
/* set reset and power button callbacks and exitTo option */
Sys_Init(); Sys_Init();
Sys_ExitTo(EXIT_TO_HBC); Sys_ExitTo(EXIT_TO_HBC);
DeviceHandle.MountAll(); /* mount Devices */
DeviceHandle.MountSD();
if(!sd_only && !Sys_DolphinMode())
DeviceHandle.MountAllUSB();
/* init wait images and show wait animation */
m_vid.setCustomWaitImgs(wait_dir, wait_loop); m_vid.setCustomWaitImgs(wait_dir, wait_loop);
m_vid.waitMessage(0.15f); m_vid.waitMessage(0.15f);
/* init controllers for input */
Open_Inputs(); Open_Inputs();
/* init configs, folders, coverflow, gui and more */
if(mainMenu.init()) if(mainMenu.init())
{ {
if(CurrentIOS.Version != mainIOS && !neek2o() && !Sys_DolphinMode()) if(CurrentIOS.Version != mainIOS && !neek2o() && !Sys_DolphinMode())
@ -114,14 +134,13 @@ int main(int argc, char **argv)
mainMenu.terror("errboot2", L"Could not find a device to save configuration files on!"); mainMenu.terror("errboot2", L"Could not find a device to save configuration files on!");
else if(WDVD_Init() < 0) else if(WDVD_Init() < 0)
mainMenu.terror("errboot3", L"Could not initialize the DIP module!"); mainMenu.terror("errboot3", L"Could not initialize the DIP module!");
else else // alls good lets start wiiflow
{ {
writeStub(); writeStub();// copy return stub to memory
if(gameid != NULL && strlen(gameid) == 6) if(gameid != NULL && strlen(gameid) == 6)// if argv game ID then launch it
mainMenu.directlaunch(gameid); mainMenu.directlaunch(gameid);
else else
mainMenu.main(); mainMenu.main();// start wiiflow with main menu displayed
//if mainMenu.init set exit=true then mainMenu.main while loop does nothing and returns to here to exit wiiflow
} }
//Exit WiiFlow, no game booted... //Exit WiiFlow, no game booted...
mainMenu.cleanup();// removes all sounds, fonts, images, coverflow, plugin stuff, source menu and clear memory mainMenu.cleanup();// removes all sounds, fonts, images, coverflow, plugin stuff, source menu and clear memory

View File

@ -138,7 +138,6 @@ bool CMenu::init()
if(drive == check) // Should not happen if(drive == check) // Should not happen
{ {
/* Could not find a device to save configuration files on! */ /* Could not find a device to save configuration files on! */
//m_exit = true;
return false; return false;
} }
@ -166,7 +165,17 @@ bool CMenu::init()
bool onUSB = m_cfg.getBool("GENERAL", "data_on_usb", strncmp(drive, "usb", 3) == 0); bool onUSB = m_cfg.getBool("GENERAL", "data_on_usb", strncmp(drive, "usb", 3) == 0);
drive = check; //reset the drive variable for the check drive = check; //reset the drive variable for the check
//check for wiiflow data directory on USB or SD based on data_on_usb //check for wiiflow data directory on USB or SD based on data_on_usb
if(onUSB) if(!onUSB)
{
if(DeviceHandle.IsInserted(SD))// no need to find sd:/wiiflow, it will be made if not exist
drive = DeviceName[SD];
else
{
onUSB = true;
m_cfg.setBool("GENERAL", "data_on_usb", true);
}
}
else // onUSB = true
{ {
for(u8 i = USB1; i <= USB8; i++) //Look for first partition with a wiiflow folder in root for(u8 i = USB1; i <= USB8; i++) //Look for first partition with a wiiflow folder in root
{ {
@ -176,12 +185,7 @@ bool CMenu::init()
break; break;
} }
} }
} if(drive == check)// if wiiflow data directory not found just find a valid USB partition
if(!onUSB && DeviceHandle.IsInserted(SD) && stat(fmt("%s:/%s", DeviceName[SD], APP_DATA_DIR), &dummy) == 0)
drive = DeviceName[SD];
if(drive == check)//if wiiflow data directory not found then check just for a USB partition or SD card
{
if(onUSB)
{ {
for(u8 i = USB1; i <= USB8; i++) for(u8 i = USB1; i <= USB8; i++)
{ {
@ -191,21 +195,16 @@ bool CMenu::init()
break; break;
} }
} }
if(drive == check && DeviceHandle.IsInserted(SD))//if no available USB partition then force SD
drive = DeviceName[SD];
else if(drive == check)
{
/* No available usb partitions for data and no SD inserted! */
//m_exit = true;
return false;
}
} }
else if(drive == check && DeviceHandle.IsInserted(SD))//if no valid USB partition then force SD if inserted
{ {
if(DeviceHandle.IsInserted(SD)) drive = DeviceName[SD];
drive = DeviceName[SD]; // show error msg later after building menus
else }
drive = DeviceName[USB1];//if no SD insterted then force USB. may set this to the wf boot.dol partition if(drive == check)// should not happen
{
/* No available usb partitions for data and no SD inserted! */
return false;
} }
} }
m_dataDir = fmt("%s:/%s", drive, APP_DATA_DIR); m_dataDir = fmt("%s:/%s", drive, APP_DATA_DIR);
@ -427,7 +426,10 @@ bool CMenu::init()
/* Init Button Manager and build the menus */ /* Init Button Manager and build the menus */
_buildMenus(); _buildMenus();
if(drive == DeviceName[SD] && onUSB) if(drive == DeviceName[SD] && onUSB)
{
error(_fmt("errboot5", L"data_on_usb=yes and No available usb partitions for data!\nUsing SD.")); error(_fmt("errboot5", L"data_on_usb=yes and No available usb partitions for data!\nUsing SD."));
m_cfg.setBool("GENERAL", "data_on_usb", false);
}
/* Check if locked, set return to, set exit to, and init multi threading */ /* Check if locked, set return to, set exit to, and init multi threading */
m_locked = m_cfg.getString("GENERAL", "parent_code", "").size() >= 4; m_locked = m_cfg.getString("GENERAL", "parent_code", "").size() >= 4;
@ -1662,12 +1664,17 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
m_vid.render(); m_vid.render();
return; return;
}*/ }*/
/* ticks - for moving and scaling covers and gui buttons and text */
if(withCF) if(withCF)
CoverFlow.tick(); CoverFlow.tick();
m_btnMgr.tick(); m_btnMgr.tick();
/* video setup */
m_vid.prepare(); m_vid.prepare();
m_vid.setup2DProjection(false, true); m_vid.setup2DProjection(false, true);
/* background and coverflow drawing */
_updateBg(); _updateBg();
if(CoverFlow.getRenderTex()) if(CoverFlow.getRenderTex())
CoverFlow.RenderTex(); CoverFlow.RenderTex();
@ -1704,6 +1711,8 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
CoverFlow.drawText(adjusting); CoverFlow.drawText(adjusting);
} }
} }
/* game video or banner drawing */
if(m_gameSelected) if(m_gameSelected)
{ {
if(m_video_playing) if(m_video_playing)
@ -1717,18 +1726,24 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
else if(m_banner.GetSelectedGame() && (!m_banner.GetInGameSettings() || (m_banner.GetInGameSettings() && m_bnr_settings))) else if(m_banner.GetSelectedGame() && (!m_banner.GetInGameSettings() || (m_banner.GetInGameSettings() && m_bnr_settings)))
m_banner.Draw(); m_banner.Draw();
} }
/* gui buttons and text drawing */
m_btnMgr.draw(); m_btnMgr.draw();
/* reading controller inputs and drawing cursor pointers*/
ScanInput(); ScanInput();
// check if we need to start screensaver
if(!m_vid.showingWaitMessage()) /* check if we want screensaver and if its idle long enuff, if so draw full screen black square with mild alpha */
{ if(!m_cfg.getBool("GENERAL", "screensaver_disabled", true))
if(!m_cfg.getBool("GENERAL", "screensaver_disabled", true)) m_vid.screensaver(NoInputTime(), m_cfg.getInt("GENERAL", "screensaver_idle_seconds", 60));
m_vid.screensaver(NoInputTime(), m_cfg.getInt("GENERAL", "screensaver_idle_seconds", 60));
m_vid.render(); /* render everything on screen */
} m_vid.render();
// check if power button is pressed and exit wiiflow // check if power button is pressed and exit wiiflow
if(Sys_Exiting()) if(Sys_Exiting())
exitHandler(BUTTON_CALLBACK); exitHandler(BUTTON_CALLBACK);
// check if we need to start playing the game/banner sound // check if we need to start playing the game/banner sound
// m_gameSelected means we are on the game selected menu // m_gameSelected means we are on the game selected menu
// m_gamesound_changed means a new game sound is loaded and ready to play // m_gamesound_changed means a new game sound is loaded and ready to play
@ -1743,15 +1758,16 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
// stop game/banner sound from playing if we exited game selected menu or if we move to new game // stop game/banner sound from playing if we exited game selected menu or if we move to new game
else if((withCF && m_gameSelected && m_gamesound_changed && m_gameSound.IsPlaying()) || (!m_gameSelected && m_gameSound.IsPlaying())) else if((withCF && m_gameSelected && m_gamesound_changed && m_gameSound.IsPlaying()) || (!m_gameSelected && m_gameSound.IsPlaying()))
m_gameSound.Stop(); m_gameSound.Stop();
/* decrease music volume to zero if any of these are true: /* decrease music volume to zero if any of these are true:
trailer video playing or trailer video playing or||
game/banner sound is being loaded because we are switching to a new game or game/banner sound is being loaded because we are switching to a new game or||
game/banner sound is loaded and ready to play or game/banner sound is loaded and ready to play or||
gamesound hasn't finished - when finishes music volume back to normal - some gamesounds don't loop continuously gamesound hasn't finished - when finishes music volume back to normal - some gamesounds don't loop continuously
also this switches to next song if current song is done */ also this switches to next song if current song is done */
MusicPlayer.Tick((withCF && (m_video_playing || (m_gameSelected && m_soundThrdBusy) || MusicPlayer.Tick((withCF && (m_video_playing || (m_gameSelected && m_soundThrdBusy) ||
(m_gameSelected && m_gamesound_changed))) || (m_gameSelected && m_gamesound_changed))) || m_gameSound.IsPlaying());
m_gameSound.IsPlaying());
// set song title and display it if music info is allowed // set song title and display it if music info is allowed
if(MusicPlayer.SongChanged() && m_music_info) if(MusicPlayer.SongChanged() && m_music_info)
{ {

View File

@ -81,7 +81,7 @@ private:
Config m_titles; Config m_titles;
Config m_version; Config m_version;
vector<string> m_homebrewArgs; //vector<string> m_homebrewArgs;
u8 *m_base_font; u8 *m_base_font;
u32 m_base_font_size; u32 m_base_font_size;
u8 *m_wbf1_font; u8 *m_wbf1_font;
@ -1088,6 +1088,7 @@ private:
void _launchGame(dir_discHdr *hdr, bool dvd, bool disc_cfg = false); void _launchGame(dir_discHdr *hdr, bool dvd, bool disc_cfg = false);
void _launchChannel(dir_discHdr *hdr); void _launchChannel(dir_discHdr *hdr);
void _launchHomebrew(const char *filepath, vector<string> arguments); void _launchHomebrew(const char *filepath, vector<string> arguments);
vector<string> _getMetaXML(const char *bootpath);
void _launchGC(dir_discHdr *hdr, bool disc); void _launchGC(dir_discHdr *hdr, bool disc);
void _launchShutdown(); void _launchShutdown();
void _setCurrentItem(const dir_discHdr *hdr); void _setCurrentItem(const dir_discHdr *hdr);

View File

@ -218,6 +218,7 @@ void CMenu::_showCFTheme(u32 curParam, int version, bool wide)
} }
break; break;
case CMenu::SCFParamDesc::PDT_FLOAT: case CMenu::SCFParamDesc::PDT_FLOAT:
// should we use wstringEx(sfmt())
m_btnMgr.setText(m_cfThemeLblVal[k], sfmt("%.2f", m_coverflow.getFloat(domain, key))); m_btnMgr.setText(m_cfThemeLblVal[k], sfmt("%.2f", m_coverflow.getFloat(domain, key)));
for (int j = 1; j < 4; ++j) for (int j = 1; j < 4; ++j)
{ {

View File

@ -244,7 +244,8 @@ void CMenu::_Explorer(void)
else if(strcasestr(file, ".dol") != NULL || strcasestr(file, ".elf") != NULL) else if(strcasestr(file, ".dol") != NULL || strcasestr(file, ".elf") != NULL)
{ {
_hideExplorer(); _hideExplorer();
_launchHomebrew(file, m_homebrewArgs); vector<string> arguments = _getMetaXML(file);
_launchHomebrew(file, arguments);
_showExplorer(); _showExplorer();
} }
else if(strcasestr(file, ".txt") != NULL || strcasestr(file, ".nfo") != NULL else if(strcasestr(file, ".txt") != NULL || strcasestr(file, ".nfo") != NULL

View File

@ -5,6 +5,9 @@
#include <time.h> #include <time.h>
#include <network.h> #include <network.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "menu.hpp" #include "menu.hpp"
#include "types.h" #include "types.h"
@ -1065,21 +1068,136 @@ void CMenu::_launch(const dir_discHdr *hdr)
} }
else if(launchHdr.type == TYPE_HOMEBREW) else if(launchHdr.type == TYPE_HOMEBREW)
{ {
const char *gamepath = fmt("%s/boot.dol", launchHdr.path); const char *bootpath = fmt("%s/boot.dol", launchHdr.path);
if(!fsop_FileExist(gamepath)) if(!fsop_FileExist(bootpath))
gamepath = fmt("%s/boot.elf", launchHdr.path); bootpath = fmt("%s/boot.elf", launchHdr.path);
if(fsop_FileExist(gamepath)) if(fsop_FileExist(bootpath))
{ {
m_cfg.setString(HOMEBREW_DOMAIN, "current_item", strrchr(launchHdr.path, '/') + 1); m_cfg.setString(HOMEBREW_DOMAIN, "current_item", strrchr(launchHdr.path, '/') + 1);
_launchHomebrew(gamepath, m_homebrewArgs); vector<string> arguments = _getMetaXML(bootpath);
/*m_homebrewArgs is basically an empty vector string not needed for homebrew _launchHomebrew(bootpath, arguments);
but used by plugins when _launchHomebrew is called */
} }
} }
ShutdownBeforeExit(); ShutdownBeforeExit();
Sys_Exit(); Sys_Exit();
} }
void CMenu::_launchHomebrew(const char *filepath, vector<string> arguments)
{
/* clear coverflow, start wiiflow wait animation, set exit handler */
_launchShutdown();
m_gcfg1.save(true);
m_gcfg2.save(true);
m_cat.save(true);
m_cfg.save(true);
Playlog_Delete();
bool ret = (LoadHomebrew(filepath) && LoadAppBooter(fmt("%s/app_booter.bin", m_binsDir.c_str())));
if(ret == false)
{
error(_t("errgame14", L"app_booter.bin not found!"));
_exitWiiflow();
}
/* no more error msgs - remove btns and sounds */
cleanup();
AddBootArgument(filepath);
for(u32 i = 0; i < arguments.size(); ++i)
{
gprintf("Argument: %s\n", arguments[i].c_str());
AddBootArgument(arguments[i].c_str());
}
ShutdownBeforeExit();// wifi and sd gecko doesnt work anymore after
loadIOS(58, false);
BootHomebrew();
Sys_Exit();
}
vector<string> CMenu::_getMetaXML(const char *bootpath)
{
char *meta_buf = NULL;
vector<string> args;
char meta_path[200];
char *p;
char *e, *end;
struct stat st;
/* load meta.xml */
p = strrchr(bootpath, '/');
snprintf(meta_path, sizeof(meta_path), "%.*smeta.xml", p ? p-bootpath+1 : 0, bootpath);
if (stat(meta_path, &st) != 0)
return args;
if (st.st_size > 64*1024)
return args;
meta_buf = (char *) calloc(st.st_size + 1, 1);// +1 so that the buf is 0 terminated
if (!meta_buf)
return args;
int fd = open(meta_path, O_RDONLY);
if (fd < 0)
{
free(meta_buf);
meta_buf = NULL;
return args;
}
read(fd, meta_buf, st.st_size);
close(fd);
/* strip comments */
p = meta_buf;
int len;
while (p && *p)
{
p = strstr(p, "<!--");
if (!p)
break;
e = strstr(p, "-->");
if (!e)
{
*p = 0; // terminate
break;
}
e += 3;
len = strlen(e);
memmove(p, e, len + 1); // +1 for 0 termination
}
/* parse meta */
if (strstr(meta_buf, "<app") && strstr(meta_buf, "</app>") && strstr(meta_buf, "<arguments>") && strstr(meta_buf, "</arguments>"))
{
p = strstr(meta_buf, "<arguments>");
end = strstr(meta_buf, "</arguments>");
do
{
p = strstr(p, "<arg>");
if (!p)
break;
p += 5; //strlen("<arg>");
e = strstr(p, "</arg>");
if (!e)
break;
string arg(p, e-p);
args.push_back(arg);
p = e + 6;
}
while (p < end);
}
free(meta_buf);
meta_buf = NULL;
return args;
}
void CMenu::_launchGC(dir_discHdr *hdr, bool disc) void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
{ {
/* note for a disc boot hdr->id is set to the disc id before _launchGC is called */ /* note for a disc boot hdr->id is set to the disc id before _launchGC is called */
@ -1343,39 +1461,6 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
Sys_Exit(); Sys_Exit();
} }
void CMenu::_launchHomebrew(const char *filepath, vector<string> arguments)
{
/* clear coverflow, start wiiflow wait animation, set exit handler */
_launchShutdown();
m_gcfg1.save(true);
m_gcfg2.save(true);
m_cat.save(true);
m_cfg.save(true);
Playlog_Delete();
bool ret = (LoadHomebrew(filepath) && LoadAppBooter(fmt("%s/app_booter.bin", m_binsDir.c_str())));
if(ret == false)
{
error(_t("errgame14", L"app_booter.bin not found!"));
_exitWiiflow();
}
/* no more error msgs - remove btns and sounds */
cleanup();
AddBootArgument(filepath);
for(u32 i = 0; i < arguments.size(); ++i)
{
gprintf("Argument: %s\n", arguments[i].c_str());
AddBootArgument(arguments[i].c_str());
}
ShutdownBeforeExit();// wifi and sd gecko doesnt work anymore after
loadIOS(58, false);
BootHomebrew();
Sys_Exit();
}
/* dont confuse loadIOS with _loadIOS */ /* dont confuse loadIOS with _loadIOS */
int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id, bool RealNAND_Channels) int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id, bool RealNAND_Channels)
{ {

View File

@ -754,7 +754,8 @@ int CMenu::main(void)
CoverFlow.clear(); CoverFlow.clear();
_showWaitMessage(); _showWaitMessage();
exitHandler(PRIILOADER_DEF); //Making wiiflow ready to boot something exitHandler(PRIILOADER_DEF); //Making wiiflow ready to boot something
_launchHomebrew(fmt("%s/boot.dol", m_appDir.c_str()), m_homebrewArgs); vector<string> arguments = _getMetaXML(fmt("%s/boot.dol", m_appDir.c_str()));
_launchHomebrew(fmt("%s/boot.dol", m_appDir.c_str()), arguments);
return 0; return 0;
} }
else if(Sys_GetExitTo() == EXIT_TO_SMNK2O || Sys_GetExitTo() == EXIT_TO_WFNK2O) else if(Sys_GetExitTo() == EXIT_TO_SMNK2O || Sys_GetExitTo() == EXIT_TO_WFNK2O)

View File

@ -150,7 +150,7 @@ void Musicplayer::LoadFile(const char *name, bool display_change)
} }
else if(FileNames.size() == 1 && strcmp(name, PLUGIN_DOMAIN) == 0) else if(FileNames.size() == 1 && strcmp(name, PLUGIN_DOMAIN) == 0)
{ {
MusicFile.FreeMemory(); MusicFile.FreeMemory();// GuiSound is MusicFile in gui_sound.cpp
MusicStopped = true; MusicStopped = true;
return; return;
} }

View File

@ -1,6 +1,6 @@
 
[SPANISH] [SPANISH]
about1=Loader original por:\n%s about1=Cargador original por:\n%s
about2=Interfaz original por:\n%s about2=Interfaz original por:\n%s
about4=Gracias a:\n%s about4=Gracias a:\n%s
about6=Desarrolladores actuales:\n%s about6=Desarrolladores actuales:\n%s
@ -8,32 +8,33 @@ about7=Desarrolladores anteriores:\n%s
about8=Parte del código obtenido desde:\n%s about8=Parte del código obtenido desde:\n%s
about9=Sitios que apoyan el proyecto:\n%s about9=Sitios que apoyan el proyecto:\n%s
about10=Guía de ayuda about10=Guía de ayuda
alphabetically=Alfabéticamente alphabetically=alfabéticamente
appname=%s v%s appname=%s v%s
aspect169=Forzar 16:9 aspect169=Forzar 16:9
aspect43=Forzar 4:3 aspect43=Forzar 4:3
aspectDef=Por Defecto aspectDef=Por defecto
bootmii=BootMii bootmii=BootMii
bycontrollers=Núm. de mandos bycontrollers=Por controles
byesrb=Clasificación ESRB byesrb=Por ESRB
bygameid=ID del juego bygameid=Por ID del juego
bylastplayed=Últimos jugados bylastplayed=Por última jugada
byplaycount=Más jugados byplaycount=Por veces jugado
byplayers=Núm. jugadores byplayers=Por jugadores
bywifiplayers=Núm. jugadores WiFi bywifiplayers=Por jugadores Wifi
cat1=Seleccionar Categorías cat1=Elegir categorías
cat2=Borrar cat2=Limpiar
cd1=Atrás cd1=Volver
cd2=Eliminar cd2=Eliminar
cd3=Bloqueo de edad cd3=Bloqueo por edad
cfg1=Configuración cfg1=Configuración
cfg10=Atrás cfg10=Volver
cfg11=Emulación de partidas en USB cfg11=Emulación de archivos en USB
cfg12=Emulación NAND cfg12=Emulación de NAND
cfg13=Configuración de emulación NAND cfg13=Ajustes de emulación de NAND
cfg14=Establecer cfg14=Ajustar
cfg15=Extras cfg15=Complementos
cfg16=Elegir cfg16=Elegir
cfg17=Particiones del juego
cfg3=Descargar carátulas y títulos cfg3=Descargar carátulas y títulos
cfg4=Descargar cfg4=Descargar
cfg5=Control parental cfg5=Control parental
@ -44,86 +45,109 @@ cfga3=Instalar
cfga6=Idioma cfga6=Idioma
cfga7=Tema cfga7=Tema
cfgb1=Ocarina cfgb1=Ocarina
cfgb3=Modo de video cfgb2=Cargador de GC por defecto
cfgb2=Cargador de GC predefinido cfgb3=Modo de video por defecto
cfgb4=Idioma del juego cfgb4=Idioma del juego por defecto
cfgb5=DML Modo de video cfgb5=Modo de video GC por defecto
cfgb6=DML Idioma del juego cfgb6=Idioma del juego GC por defecto
cfgb7=Tipo de canales
cfgb8=Ajustes de GameCube
cfgb9=Ajustes de GameCube por defecto
cfgbnr1=Descargar carátula cfgbnr1=Descargar carátula
cfgbnr2=Borrar carátula cfgbnr2=Borrar carátula
cfgbnr3=Descargar Banner personalizado cfgbnr3=Descargar banner personalizado
cfgbnr4=Borrar Banner cfgbnr4=Borrar banner
cfgbnr5=Descargar cfgbnr5=Descargar
cfgbnr6=Borrar cfgbnr6=Borrar
cfgbt1=Configuración de inicio cfgbt1=Ajustes de inicio
cfgbt2=Forzar carga de cIOS cfgbt2=Forzar carga de cIOS
cfgbt3=Forzar revisión de cIOS cfgbt3=Forzar revisión de cIOS
cfgbt4=Puerto USB cfgbt4=Puerto USB
cfgbt5=Mostrar menú de fuentes al iniciar cfgbt5=Mostrar menú de fuentes al iniciar
cfgbt6=Activar funciones de varias fuentes cfgbt6=Activar funciones multifuente
cfgbt7=Iniciar servidor FTP al inicio cfgbt7=Iniciar servidor FTP al inicio
cfgc1=Salir a cfgc1=Salir a
cfgc2=Ajustar ancho cfgc2=Ajustar ancho TV
cfgc3=Ajustar altura cfgc3=Ajustar altura TV
cfgc4=Ajustar Coverflow cfgc4=Ajustar Coverflow
cfgc5=Ajustar cfgc5=Ajustar
cfgc6=Ajuste horizontal cfgc6=Ajuste horizontal
cfgc7=Ajuste vertical cfgc7=Ajuste vertical
cfgc8=Configuración de inicio cfgc8=Configuración de inicio
cfgc9=Manejar idiomas cfgc9=Idiomas de WiiFlow
cfgd4=Manejador de parches cfgd4=Gestor de ubicación
cfgd5=Guardar el modo favorito cfgd5=Guardar el modo favorito
cfgd7=Mostrar categorías al iniciar cfgd7=Mostrar categorías al iniciar
cfgg1=Configuración cfgg1=Ajustes
cfgg10=IOS cfgg10=IOS
cfgg12=Descargar carátula cfgg11=
cfgg13=Descargar cfgg12=
cfgg14=Parchar video cfgg13=
cfgg15=Trucos cfgg14=Parchar modos de video
cfgg15=Códigos de trampa
cfgg16=Elegir cfgg16=Elegir
cfgg17=Elegir categorías cfgg17=Categorías
cfgg18=Tipo de enganche cfgg18=Tipo de gancho
cfgg19=
cfgg2=Modo de video cfgg2=Modo de video
cfgg20=
cfgg21=Volver al canal cfgg21=Volver al canal
cfgg22=Depurador cfgg22=Depurador
cfgg23=Descargando trucos.... cfgg23=Descargando archivo de trampas....
cfgg24=Emulación NAND cfgg24=Emulación de NAND
cfgg25=Contraseña incorrecta cfgg25=Contraseña incorrecta
cfgg26=Desactivar bloque de recarga de IOS cfgg26=
cfgg27=Relación de aspecto cfgg27=Relación de aspecto
cfgg28=NMM cfgg28=
cfgg29=No parche DVD cfgg29=
cfgg3=Idioma cfgg3=Idioma
cfgg30=Extraer partida de NAND cfgg30=Extraer partida de NAND
cfgg31=Extraer cfgg31=Extraer
cfgg32=Copiar partida a NAND cfgg32=Copiar partida a NAND
cfgg33=Copiar cfgg33=Copiar
cfgg34=Emulador de memoria de Devolution cfgg34=
cfgg35=Cargador de GameCube cfgg35=Cargador de GameCube
cfgg36=Parche pantalla ancha cfgg36=Parche pantalla ancha
cfgg37=Cargar Apploader cfgg37=Apploader de inicio
cfgg38=LED de actividad cfgg38=LED de actividad
cfgg39=Captura de pantalla DM cfgg39=
cfgg40=Manejar Carátula y Banner cfgg40=Gestionar carátula y banner
cfgg41=Manejar cfgg41=Gestionar
cfgg4=Parchar frases de país cfgg42=Control USB-HID
cfgg43=Control nativo
cfgg44=Antiparpadeo de video
cfgg45=Servidor privado
cfgg46=Pantalla ancha en WiiU
cfgg47=Memoria emulada
cfgg48=Modo arcade Triforce
cfgg50=¡No hay partida a extraer!
cfgg51=¡No hay partida a meter en la NAND!
cfgg52=Vibración de GC en Wiimote
cfgg53=Saltar BIOS IPL
cfgg54=Ancho del video
cfgg55=Posición del video
cfgg56=Parchar PAL50
cfgg57=¡No permitido para discos!
cfgg4=Parchar cadenas de país
cfgg5=Ocarina cfgg5=Ocarina
cfgg6=
cfgg7=Vipatch cfgg7=Vipatch
cfgg8=Volver cfgg8=Volver
cfglng1=Manejar idiomas cfgg9=
cfglng1=Gestionar idiomas
cfglng2=Obtener idiomas cfglng2=Obtener idiomas
cfglng3=Seleccionar archivo cfglng3=Elegir archivo
cfglng4=Descargar archivo seleccionado cfglng4=Descargar archivo elegido
cfgne1=Emulación de NAND cfgne1=Emulación de NAND
cfgne2=Extraer partidas cfgne2=Extraer partidas
cfgne3=Todas cfgne3=Todas
cfgne4=Faltantes cfgne4=Faltantes
cfgne5=Extraer NAND cfgne5=Extraer NAND
cfgne6=Empezar cfgne6=Empezar
cfgne7=Atrás cfgne7=Volver
cfgne8=¡No se encontró partición FAT válida para emulación de NAND! cfgne8=¡No se encontró partición FAT válida para emulación de NAND!
cfgne9=Archivo actual: %s cfgne9=Archivo actual: %s
cfgne10=Opciones para emulación de NAND cfgne10=Ajustes de emulación de NAND
cfgne11=Progreso total: cfgne11=Progreso total:
cfgne12=Extractor de NAND cfgne12=Extractor de NAND
cfgne13=Extractor de partidas cfgne13=Extractor de partidas
@ -132,70 +156,76 @@ cfgne15=Extraídos: %d archivos / %d carpetas
cfgne16=Tamaño total: %uMB (%d bloques) cfgne16=Tamaño total: %uMB (%d bloques)
cfgne17=Tamaño total: %uKB (%d bloques) cfgne17=Tamaño total: %uKB (%d bloques)
cfgne18=Listando partidas a extraer... cfgne18=Listando partidas a extraer...
cfgne19=¡La extracción termino! cfgne19=¡Extracción terminada!
cfgne20=¡La extracción falló! cfgne20=¡Extracción fallida!
cfgne22=Desactivar emulación de NAND cfgne21=
cfgne23=Bienvenido a WiiFlow. No encontré una NAND válida para emulación de NAND. Pulse Extraer para extraer su NAND, o pulse desactivar para desactivar la emulación de NAND. cfgne22=
cfgne24=Extraer partida guardada cfgne23=
cfgne24=Extraer partida
cfgne25=Crear nueva partida cfgne25=Crear nueva partida
cfgne26=Una nueva partida se ha creado para este juego en la NAND real. ¿Extraer partida guardada existente de la NAND real o crear un nuevo archivo para emulación de NAND? cfgne26=Un archivo de guardado fue creado para este juego en la NAND real. ¿Extraer partida existente en la NAND real o crear una nueva para la emulación de NAND?
cfgne27=Calculando espacio necesario para extracción... cfgne27=Calculando espacio necesario para la extracción...
cfgne28=Importar partida guardada cfgne28=Grabador de partidas
cfgne29=Importados: %d partidas / %d archivos / %d directorios cfgne29=Grabados: %d partidas / %d archivos / %d directorios
cfgne30=¡Importación de archivos finalizada! cfgne30=¡Grabado de partidas finalizado!
cfgne31=Seleccionar partición cfgne31=
cfgne32=Cambiar Nand cfgne32=Elegir NAND de partidas
cfgne32=Cambiar Nand de guardado cfgne32=Emulación de NAND de partidas
cfgne34=Ajustar cfgne34=Ajustar
cfgne35=Atrás cfgne35=Volver
cfgne36=Ubicación = cfgne36=Ubicación =
cfgne37=Escoger NAND predefinida cfgne37=Elegir NAND por defecto
cfgne38=Vacío cfgne38=Vacío
cfgp1=Partición de juegos cfgp1=Partición de NAND de partidas
cfgp2=Carátulas planas cfgp2=Carátulas planas
cfgp3=Conectar a la red al inicio cfgp3=Conectar red al inicio
cfgp4=Caché de banners cfgp4=Caché de banners
cfgp5=Juegos de Wii cfgp5=Juegos de Wii
cfgp6=Juegos de GC cfgp6=Juegos de GC
cfgp7=Música cfgp7=Música
cfgp8=Carátulas de cajas cfgp8=Carátulas de cajas
cfgp9=Banners personalizados cfgp9=Banners personalizados
cfgpl1=Seleccionar extras cfgpl1=Elegir complementos
cfgs1=Volumen de la música cfgs1=Volumen de la música
cfgs2=Volumen de la interfaz cfgs2=Volumen de la interfaz
cfgs3=Volumen de Coverflow cfgs3=Volumen del coverflow
cfgs4=Volumen del juego cfgs4=Volumen del juego
cfgsm1=Ajustes del menú de fuentes cfgsm1=Ajustes del menú de fuentes
cfgsm2=Activar B para menú de fuentes
cfgsm3=Activar Sourceflow cfgsm3=Activar Sourceflow
cfgsm4=Cajas chicas para Sourceflow cfgsm4=Cajas chicas para Sourceflow
cfgsm5=Limpiar caché de Sourceflow cfgsm5=Limpiar caché de Sourceflow
cfgsm6=B en modo para fuente cfghb1=Ajustes de Homebrew
cfgsm7=Manejar menú de fuentes cfghb2=Cajas chicas para Coverflow
cfghb3=Partición de Homebrew
cfghb4=Modo de caja
cfghb5=Descargar carátulas
ChanReal=NAND real
ChanEmu=NAND emulada
ChanBoth=Ambas
cheat1=Volver cheat1=Volver
cheat2=Aplicar cheat2=Aplicar
cheat3=Archivo de trucos para el juego no encontrado cheat3=Archivo de trampas para el juego no encontrado.
cheat4=Descarga no encontrada. cheat4=Descarga no encontrada.
commodore=Commodore 64 commodore=Commodore 64
custom=Personalizado custom=Personalizado
def=Por Defecto def=Por defecto
disabled=Desactivado disabled=Desactivado
dl1=Cancelar dl1=Cancelar
dl10=Por favor dona\na GameTDB.com dl10=Por favor dona\na GameTDB.com
dl12=GameTDB dl12=GameTDB
dl13=Orden de descarga dl13=Orden de descarga
dl14=Elija regiones donde buscar carátulas: dl14=Elige las regiones para buscar carátulas:
dl15=Configuración de descarga dl15=Configuración de descarga
dl16=Establecer dl16=Ajustar
dl17=Configuración de descarga dl17=Configuración de descarga
dl18=Atrás dl18=Volver
dl19=Solo original dl19=Solo original
dl2=Atrás dl2=Volver
dl20=Original/Original dl20=Original/Original
dl21=Original/Personal dl21=Original/Personalizada
dl22=Personal/Original dl22=Personalizada/Original
dl23=Personal/Personal dl23=Personalizada/Personalizada
dl24=Solo personal dl24=Solo personalizada
dl25=Todas dl25=Todas
dl3=Todas dl3=Todas
dl4=Faltantes dl4=Faltantes
@ -211,9 +241,9 @@ dlmsg14=Terminado.
dlmsg15=¡Falló el guardando! dlmsg15=¡Falló el guardando!
dlmsg16=No se pudo leer el archivo dlmsg16=No se pudo leer el archivo
dlmsg17=¡No hay actualizaciones! dlmsg17=¡No hay actualizaciones!
dlmsg18=boot.dol no encontrado en la carpeta predeterminada dlmsg18=boot.dol no encontrado en la ubicación predeterminada
dlmsg19=¡Actualización disponible! dlmsg19=¡Actualización disponible!
dlmsg2=No se pudo inicializar la red dlmsg2=No se pudo conectar a la red
dlmsg20=No se ha encontrado información sobre la versión dlmsg20=No se ha encontrado información sobre la versión
dlmsg21=WiiFlow se cerrará para que los cambios tengan efecto. dlmsg21=WiiFlow se cerrará para que los cambios tengan efecto.
dlmsg22=Actualizando directorio de la aplicación... dlmsg22=Actualizando directorio de la aplicación...
@ -221,7 +251,7 @@ dlmsg23=Actualizando directorio de datos
dlmsg24=Extrayendo... dlmsg24=Extrayendo...
dlmsg25=¡La extracción ha fallado! Renombrando la copia de seguridad a boot.dol dlmsg25=¡La extracción ha fallado! Renombrando la copia de seguridad a boot.dol
dlmsg26=Actualizando caché... dlmsg26=Actualizando caché...
dlmsg27=¡Falta memoria! dlmsg27=¡No hay suficiente memoria!
dlmsg28=Ejecutando servidor FTP en %s:%u dlmsg28=Ejecutando servidor FTP en %s:%u
dlmsg29=El servidor FTP se encuentra detenido. dlmsg29=El servidor FTP se encuentra detenido.
dlmsg3=Descargando desde %s dlmsg3=Descargando desde %s
@ -238,10 +268,10 @@ DMLpal=PAL 576i
DMLpal60=PAL 480i DMLpal60=PAL 480i
DMLprog=NTSC 480p DMLprog=NTSC 480p
DMLprogP=PAL 480p DMLprogP=PAL 480p
errboot1=¡No se encontró cIOS!\ncIOS d2x 249 base 56 y 250 base 57 son suficientes para todos sus juegos. errboot1=¡No se encontró cIOS!\ncIOS d2x 249 base 56 y 250 base 57 son suficientes para todos tus juegos.
errboot2=¡No se encontró un dispositivo donde guardar los archivos de configuración! errboot2=¡No se encontró un dispositivo donde guardar los archivos de configuración!
errboot3=¡No se pudo iniciar el módulo DIP! errboot3=¡No se pudo iniciar el módulo DIP!
errboot4=¡No se encontraron particiones disponibles! errboot4=¡No se encontró el directorio apps/wiiflow!
errboot5=data_on_usb=yes, ¡pero no hay particiones USB disponibles para datos!\nUsando SD. errboot5=data_on_usb=yes, ¡pero no hay particiones USB disponibles para datos!\nUsando SD.
errboot6=¡No hay particiones USB disponibles para datos ni tarjeta SD insertada!\nSaliendo. errboot6=¡No hay particiones USB disponibles para datos ni tarjeta SD insertada!\nSaliendo.
errgame1=No se encontró un juego con el ID: %s errgame1=No se encontró un juego con el ID: %s
@ -250,17 +280,26 @@ errgame4=No se pudo cargar el IOS %i
errgame5=¡Falló la activación del emu! errgame5=¡Falló la activación del emu!
errgame6=¡Falló la activación del emu luego de recargar! errgame6=¡Falló la activación del emu luego de recargar!
errgame7=¡Falló WDVDGetCoverStatus! errgame7=¡Falló WDVDGetCoverStatus!
errgame8=Por favor, inserte un dico de juego. errgame8=Por favor, inserta un dico de juego.
errgame9=Esto no es un disco de Wii o GC errgame9=Esto no es un disco de Wii o GC
errgame10=Falló ajuste de USB: %d errgame11=¡Cargador de GameCube no encontrado! No se puede lanzar el juego.
errneek1=No se pudo iniciar neek2o. Verifique sus ajustes de neek2o errgame12=¡Nintendont no encontrado! No se puede lanzar el disco de GC.
errgame13=¡EmuNAND para la partida no encontrado! Usando NAND real.
errgame14=¡app_booter.bin no encontrado!
errgame15=¡WiiFlow bloqueado! Desbloquea WiiFlow para usar esta función.
errgame16=¡No disponible para juegos de complementos!
errgame17=¡No se pueden eliminar canales de la NAND real!
errgame18=¡No hay info del juego!
errneek1=No se pudo iniciar neek2o. Verifica tu instalación de neek2o
errsource1=¡Homebrew bloqueado!
errsource2=¡Homebrew y multifuente no permitidos!
exit_to=Salir a exit_to=Salir a
ftp1=Iniciar ftp1=Iniciar
ftp2=Detener ftp2=Detener
gameinfo1=Desarrollador: %s gameinfo1=Desarrollador: %s
gameinfo2=Distribuidor: %s gameinfo2=Distribuidor: %s
gameinfo3=Región: %s gameinfo3=Región: %s
gameinfo4=Fecha de lanzamiento: %i.%i.%i gameinfo4=Lanzamiento: %i.%i.%i
gameinfo5=Género: %s gameinfo5=Género: %s
gameinfo6=Sin información del juego gameinfo6=Sin información del juego
gametdb_code=ES gametdb_code=ES
@ -270,7 +309,7 @@ GC_Devo=Devolution
GC_Auto=Auto GC_Auto=Auto
genesis=Sega Genesis genesis=Sega Genesis
gm1=Jugar gm1=Jugar
gm2=Atrás gm2=Volver
hbc=HBC hbc=HBC
homebrew=Homebrew homebrew=Homebrew
home1=Ajustes home1=Ajustes
@ -304,43 +343,51 @@ lngspa=Español
lngsys=Sistema lngsys=Sistema
lngtch=Chino T. lngtch=Chino T.
main1=Instalar Juego main1=Instalar Juego
main2=Bienvenido a WiiFlow. No encontré ningún juego. Pulse Instalar para instalar un juego o Seleccionar partición para seleccionar su tipo de partición. main2=No se encontraron juegos en
main3=Seleccionar partición main3=No se encontraron títulos en
main4=Bienvenido a WiiFlow. No encontré ningún juego Pulse Seleccionar partición para elegir su tipo de partición. main4=No se encontraron apps en
main5=Bienvenido a WiiFlow. No encontré ningún complemento. Pulse Seleccionar partición para elegir su tipo de partición. main5=No se encontraron roms/elementos.
main6=No hay complementos elegidos.
main7=Total de juegos: %u
mastersystem=Sega Master System mastersystem=Sega Master System
menu=Menú del sistema menu=Menú del sistema
NANDfull=Completa NANDfull=Completa
NANDoff=Desactivado NANDoff=Desactivada
NANDpart=Parcial NANDpart=Parcial
neek1=Lanzar título con neek2o neek1=Lanzar título con neek2o
neek2o=neek2o neek2o=neek2o
neogeo=Neo-Geo neogeo=Neo-Geo
nes=Nintendo nes=Nintendo
nintendo64=Nintendo64 nintendo64=Nintendo64
NMMdebug=Depurar
NMMDef=Por defecto NMMDef=Por defecto
NMMOff=Desactivado NMMOff=Desactivado
NMMon=Activado NMMon=Activado
NMMdebug=Depurar
NoDVDDef=Por defecto NoDVDDef=Por defecto
NoDVDOff=Desactivado NoDVDOff=Desactivado
NoDVDon=Activado NoDVDon=Activado
off=Desactivado off=Desactivado
on=Activado on=Activado
players=Jugadores part1=Partición de Wii
part2=Partición de GameCube
part3=Partición de Emu NANDs
part4=Partición de complementos
part5=Ajustes de particiones
players= jugadores
prii=Priiloader prii=Priiloader
real=Nand real real=Nand real
SaveDef=Por defecto SaveDef=Por defecto
SaveFull=Completa SaveFull=Completa
SaveFullG=Completa SaveFullG=Completa
SaveOff=Desactivado SaveOff=Desactivada
SaveOffG=Desactivado SaveOffG=Desactivada
SavePart=Partida guardada SavePart=Partida guardada
SavePartG=Partida guardada SavePartG=Partida guardada
SaveReg=Cambio de región SaveReg=Cambio de región
SaveRegG=Cambio de región SaveRegG=Cambio de región
savedtheme=¡Configuración del tema guardada!
snes=Super Nintendo snes=Super Nintendo
stup1=Seleccione fuente stup1=Elegir fuente
stup2=** DESACTIVADO ** stup2=** DESACTIVADO **
sys1=Actualizar WiiFlow sys1=Actualizar WiiFlow
sys2=Versión de WiiFlow: sys2=Versión de WiiFlow:
@ -363,46 +410,49 @@ vmpmore=Más
vmpnone=Ninguno vmpnone=Ninguno
vmpnormal=Normal vmpnormal=Normal
wad1=Instalar WAD wad1=Instalar WAD
wad2=Comenzar wad2=Empezar
wad3=Seleccionado %s, después de la instalación usted regresará al explorador. wad3=
wad4=Instalando WAD, por favor espere... wad4=Instalando WAD, por favor espera...
wad5=Error de instalación %i! wad5=Error de instalación %i!
wad6=Instalación finalizada con %i errores de hash. wad6=Instalación finalizada con %i errores de hash.
wbfsadddlg=Por favor inserte el disco que quiera copiar, y pulse Ir. wad7=Listo para instalar %s\nElige emuNAND y aprieta en Empezar.
wbfscpydlg=Si quiere copiar este juego a la tarjeta SD, pulse Ir wbfsadddlg=Por favor, inserta el disco que quieres copiar, y aprieta Empezar.
wbfsop1=Instalar Juego wbfscpydlg=Si quieres copiar este juego a la tarjeta SD, aprieta Empezar
wbfsop1=Instalar juego
wbfsop10=Copiando [%s] %s... wbfsop10=Copiando [%s] %s...
wbfsop11=Copiar juego wbfsop11=Copiar juego
wbfsop12=Error en DVD(%d) wbfsop12=DVDError(%d)
wbfsop13=Juego instalado, pero el disco tiene errores (%d) wbfsop13=Juego instalado, pero el disco tiene errores (%d)
wbfsop14=Juego copiado, pulse volver para iniciar el juego. wbfsop14=Juego copiado, presiona Volver para iniciar el juego.
wbfsop15=Calculando espacio necesario para %s wbfsop15=Calculando espacio necesario para %s
wbfsop16=Instalando %s wbfsop16=Instalando %s
wbfsop17=Instalando %s disco %d/2 wbfsop17=Instalando %s disco %d/2
wbfsop18=¡Esto es un juego de Wii! wbfsop18=¡Esto es un juego de Wii!
wbfsop19=¡Esto no es un juego de Gamecube! wbfsop19=¡Esto no es un juego de GameCube!
wbfsop2=Borrar juego wbfsop2=Borrar juego
wbfsop20=¡Ha insertado otra vez el disco %d! wbfsop20=¡Has insertado otra vez el disco %d!
wbfsop21=¡¡Este es un disco de otro juego!! wbfsop21=¡¡Este es un disco de otro juego!!
wbfsop22=Instalando %s...\n Por favor, inserte el disco 2 para continuar wbfsop22=Instalando %s...\n Por favor, inserta el disco 2 para continuar
wbfsop23=Calculando espacio necesario para %s...\n Por favor, inserte el disco %d para continuar wbfsop23=Calculando espacio necesario para %s...\n Por favor, inserta el disco %d para continuar
wbfsop24=No hay espacio suficiente: %d bloques necesarios, %d disponible wbfsop24=No hay espacio suficiente: %d bloques necesarios, %d disponibles
wbfsop25=¡Error leyendo disco! Pruebe limpiar el disco wbfsop25=¡Error leyendo el disco! Prueba a limpiar el disco
wbfsop26=¡¡Disco extraído!! Por favor, inserte el disco wbfsop26=¡¡Disco extraído!! Por favor, inserta el disco
wbfsop4=Atrás wbfsop4=Volver
wbfsop5=Ir wbfsop5=Empezar
wbfsop6=Instalando [%s] %s... wbfsop6=Instalando [%s] %s...
wbfsop7=Juego eliminado wbfsop7=Juego borrado
wbfsop8=Juego instalado, presiona B para salir. wbfsop8=Juego instalado, presiona B para salir.
wbfsop9=Ha ocurrido un error wbfsop9=Ha ocurrido un error
wbfsoperr1=Disc_Wait falló wbfsoperr1=Disc_Wait falló
wbfsoperr2=Disc_Open falló wbfsoperr2=Disc_Open falló
wbfsoperr3=¡Esto no es un disco de Wii! wbfsoperr3=¡Esto no es un disco de Wii!
wbfsoperr4=El juego ya esta instalado wbfsoperr4=El juego ya está instalado
wbfsoperr5=¡No se permite eliminar este canal! wbfsoperr5=¡Eliminar este canal no está permitido!
wbfsoperr6=El instalador de juegos de Wii esta malo, por favor usa cleanrip.
wbfsprogress=%i%% wbfsprogress=%i%%
wbfsremdlg=Para eliminar el juego permanentemente : %s, presione Ir. wbfsremdlg=Para eliminar permanentemente el juego: %s, presiona Empezar.
wifiplayers= jugadores WiFi wifiplayers= jugadores WiFi
wii=Wii wii=Wii
wiichannels=Canales de Wii wiichannels=Canales de Wii oficiales
wiiware=WiiWare wiiware=WiiWare
wiiu=Menú de Wii U