2012-10-03 23:34:37 +02:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <unistd.h>
|
2016-04-21 02:05:28 +02:00
|
|
|
#include <algorithm>
|
2018-08-07 01:28:06 +02:00
|
|
|
#include <sys/stat.h>
|
2012-05-03 01:08:11 +02:00
|
|
|
#include "menu.hpp"
|
2012-08-05 15:48:15 +02:00
|
|
|
#include "lockMutex.hpp"
|
|
|
|
#include "channel/nand.hpp"
|
|
|
|
#include "loader/cios.h"
|
2012-08-11 14:27:38 +02:00
|
|
|
#include "loader/nk.h"
|
2012-05-03 01:08:11 +02:00
|
|
|
|
2012-06-08 15:05:21 +02:00
|
|
|
// NandEmulation menu
|
2012-09-13 16:54:17 +02:00
|
|
|
s16 m_nandemuLblTitle;
|
|
|
|
s16 m_nandemuBtnBack;
|
2013-07-10 17:08:40 +02:00
|
|
|
s16 m_nandemuLblPage;
|
|
|
|
s16 m_nandemuBtnPageM;
|
|
|
|
s16 m_nandemuBtnPageP;
|
2022-07-07 00:34:55 +02:00
|
|
|
s16 m_nandemuLblUser[4];
|
2016-12-01 01:05:39 +01:00
|
|
|
|
2012-09-13 16:54:17 +02:00
|
|
|
s16 m_nandfileLblMessage;
|
|
|
|
s16 m_nandemuLblMessage;
|
|
|
|
s16 m_nandfileLblDialog;
|
|
|
|
s16 m_nandfinLblDialog;
|
|
|
|
s16 m_nandemuLblDialog;
|
|
|
|
s16 m_nandfilePBar;
|
|
|
|
s16 m_nandemuPBar;
|
2022-07-07 00:34:55 +02:00
|
|
|
|
2012-12-28 15:19:40 +01:00
|
|
|
TexData m_nandemuBg;
|
2012-06-08 15:05:21 +02:00
|
|
|
|
2013-07-10 17:08:40 +02:00
|
|
|
int nandemuPage = 1;
|
2017-09-22 00:03:41 +02:00
|
|
|
int curEmuNand = 0;
|
|
|
|
int curSavesNand = 0;
|
|
|
|
vector<string> emuNands;
|
|
|
|
vector<string> savesNands;
|
2012-06-08 15:05:21 +02:00
|
|
|
bool m_nandext;
|
2018-07-09 16:53:35 +02:00
|
|
|
bool m_nanddump;
|
2012-06-08 15:05:21 +02:00
|
|
|
bool m_sgdump;
|
|
|
|
bool m_saveall;
|
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
static inline int loopNum(int i, int s)
|
|
|
|
{
|
2016-04-03 02:51:40 +02:00
|
|
|
return (i + s) % s;
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
|
|
|
|
2022-07-07 00:34:55 +02:00
|
|
|
void CMenu::_hideNandEmu(bool instant)
|
|
|
|
{
|
|
|
|
m_btnMgr.hide(m_nandemuLblTitle, instant);
|
|
|
|
m_btnMgr.hide(m_nandemuBtnBack, instant);
|
|
|
|
m_btnMgr.hide(m_nandemuLblPage, instant);
|
|
|
|
m_btnMgr.hide(m_nandemuBtnPageM, instant);
|
|
|
|
m_btnMgr.hide(m_nandemuBtnPageP, instant);
|
|
|
|
for(u8 i = 0; i < ARRAY_SIZE(m_nandemuLblUser); ++i)
|
|
|
|
if(m_nandemuLblUser[i] != -1)
|
|
|
|
m_btnMgr.hide(m_nandemuLblUser[i], instant);
|
|
|
|
|
|
|
|
_hideConfigButtons(instant);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenu::_showNandEmu(void)
|
|
|
|
{
|
|
|
|
_setBg(m_nandemuBg, m_nandemuBg);
|
|
|
|
m_btnMgr.setText(m_nandemuLblTitle, _t("cfgne10", L"NAND Emulation Settings"));
|
|
|
|
m_btnMgr.show(m_nandemuLblTitle);
|
|
|
|
m_btnMgr.show(m_nandemuBtnBack);
|
|
|
|
for(u8 i = 0; i < ARRAY_SIZE(m_nandemuLblUser); ++i)
|
|
|
|
if(m_nandemuLblUser[i] != -1)
|
|
|
|
m_btnMgr.show(m_nandemuLblUser[i]);
|
|
|
|
|
|
|
|
m_btnMgr.setText(m_nandemuLblPage, wfmt(L"%i / 3", nandemuPage));
|
|
|
|
m_btnMgr.show(m_nandemuLblPage);
|
|
|
|
m_btnMgr.show(m_nandemuBtnPageM);
|
|
|
|
m_btnMgr.show(m_nandemuBtnPageP);
|
|
|
|
|
|
|
|
_hideConfigButtons(true);
|
|
|
|
|
|
|
|
if(nandemuPage == 1)
|
|
|
|
{
|
2022-09-07 16:33:31 +02:00
|
|
|
m_btnMgr.setText(m_configLbl1Val, m_cfg.getString(CHANNEL_DOMAIN, "current_emunand"));
|
2022-07-07 00:34:55 +02:00
|
|
|
|
|
|
|
int i = min(max(0, m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0)), (int)ARRAY_SIZE(CMenu::_NandEmu) - 1);
|
|
|
|
m_btnMgr.setText(m_configLbl2Val, _t(CMenu::_NandEmu[i].id, CMenu::_NandEmu[i].text));
|
|
|
|
|
2022-09-07 16:33:31 +02:00
|
|
|
m_btnMgr.setText(m_configLbl3Val, m_cfg.getString(WII_DOMAIN, "current_save_emunand"));
|
2022-07-07 00:34:55 +02:00
|
|
|
|
|
|
|
i = min(max(0, m_cfg.getInt(WII_DOMAIN, "save_emulation", 0)), (int)ARRAY_SIZE(CMenu::_GlobalSaveEmu) - 1);
|
|
|
|
m_btnMgr.setText(m_configLbl4Val, _t(CMenu::_GlobalSaveEmu[i].id, CMenu::_GlobalSaveEmu[i].text));
|
|
|
|
|
|
|
|
m_btnMgr.setText(m_configLbl1, _t("cfgne37", L"Select NAND"));
|
|
|
|
m_btnMgr.setText(m_configLbl2, _t("cfgne1", L"NAND Emulation"));
|
|
|
|
m_btnMgr.setText(m_configLbl3, _t("cfgne32", L"Select Saves NAND"));
|
|
|
|
m_btnMgr.setText(m_configLbl4, _t("cfgne33", L"Saves NAND Emulation"));
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl1);
|
|
|
|
m_btnMgr.show(m_configLbl1Val);
|
|
|
|
m_btnMgr.show(m_configBtn1P);
|
|
|
|
m_btnMgr.show(m_configBtn1M);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl2);
|
|
|
|
m_btnMgr.show(m_configLbl2Val);
|
|
|
|
m_btnMgr.show(m_configBtn2P);
|
|
|
|
m_btnMgr.show(m_configBtn2M);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl3);
|
|
|
|
m_btnMgr.show(m_configLbl3Val);
|
|
|
|
m_btnMgr.show(m_configBtn3P);
|
|
|
|
m_btnMgr.show(m_configBtn3M);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl4);
|
|
|
|
m_btnMgr.show(m_configLbl4Val);
|
|
|
|
m_btnMgr.show(m_configBtn4P);
|
|
|
|
m_btnMgr.show(m_configBtn4M);
|
|
|
|
}
|
|
|
|
else if(nandemuPage == 2)
|
|
|
|
{
|
|
|
|
m_btnMgr.setText(m_configLbl1, _t("cfgne2", L"Extract Game Saves"));
|
|
|
|
m_btnMgr.setText(m_configBtn1, _t("cfgne3", L"All"));
|
|
|
|
m_btnMgr.setText(m_configBtn2, _t("cfgne4", L"Missing"));
|
|
|
|
m_btnMgr.setText(m_configLbl3, _t("cfgne5", L"Extract NAND"));
|
|
|
|
m_btnMgr.setText(m_configBtn3, _t("cfgne6", L"Start"));
|
|
|
|
m_btnMgr.setText(m_configLbl4, _t("cfgne98", L"Install Wad"));
|
|
|
|
m_btnMgr.setText(m_configBtn4, _t("cfgne99", L"Go"));
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl1);
|
|
|
|
m_btnMgr.show(m_configBtn1);
|
|
|
|
m_btnMgr.show(m_configBtn2);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl3);
|
|
|
|
m_btnMgr.show(m_configBtn3);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl4);
|
|
|
|
m_btnMgr.show(m_configBtn4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_btnMgr.setText(m_configLbl1, _t("cfgne38", L"Saves NAND Partition"));
|
2022-12-10 22:10:29 +01:00
|
|
|
currentPartition = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
|
|
|
m_btnMgr.setText(m_configLbl1Val, upperCase(DeviceName[currentPartition]));
|
2022-07-07 00:34:55 +02:00
|
|
|
|
|
|
|
m_btnMgr.setText(m_configLbl2, _t("cfgne40", L"Use Real NAND Config"));
|
|
|
|
m_btnMgr.setText(m_configBtn2, m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_config", false) ? _t("on", L"On") : _t("off", L"Off"));
|
2022-12-10 22:10:29 +01:00
|
|
|
|
|
|
|
m_btnMgr.setText(m_configLbl3, _t("cfgne41", L"Use Real NAND Miis"));
|
2022-07-07 00:34:55 +02:00
|
|
|
m_btnMgr.setText(m_configBtn3, m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_miis", false) ? _t("on", L"On") : _t("off", L"Off"));
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl1);
|
|
|
|
m_btnMgr.show(m_configLbl1Val);
|
|
|
|
m_btnMgr.show(m_configBtn1P);
|
|
|
|
m_btnMgr.show(m_configBtn1M);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl2);
|
|
|
|
m_btnMgr.show(m_configBtn2);
|
|
|
|
|
|
|
|
m_btnMgr.show(m_configLbl3);
|
|
|
|
m_btnMgr.show(m_configBtn3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CMenu::_NandEmuCfg(void)
|
|
|
|
{
|
|
|
|
if(isWiiVC)
|
|
|
|
{
|
2022-07-14 00:11:44 +02:00
|
|
|
_error(_t("errboot7", L"Access denied in Wii VC mode."));
|
2022-07-07 00:34:55 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
s8 direction;
|
|
|
|
nandemuPage = 1;
|
|
|
|
string ExtNand = "";
|
|
|
|
string emuNand = m_cfg.getString(CHANNEL_DOMAIN, "current_emunand");
|
|
|
|
lwp_t thread = 0;
|
|
|
|
SetupInput();
|
|
|
|
_getEmuNands();
|
|
|
|
_showNandEmu();
|
|
|
|
|
|
|
|
m_thrdStop = false;
|
|
|
|
m_thrdMessageAdded = false;
|
|
|
|
m_nandext = false;
|
|
|
|
|
|
|
|
while(!m_exit)
|
|
|
|
{
|
|
|
|
_mainLoopCommon();
|
|
|
|
if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnPageM)))
|
|
|
|
{
|
|
|
|
if(nandemuPage == 1)
|
|
|
|
nandemuPage = 3;
|
|
|
|
else --nandemuPage;
|
|
|
|
if(BTN_LEFT_PRESSED || BTN_MINUS_PRESSED)
|
|
|
|
m_btnMgr.click(m_nandemuBtnPageM);
|
|
|
|
_showNandEmu();
|
|
|
|
}
|
|
|
|
else if((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnPageP)))
|
|
|
|
{
|
|
|
|
if(nandemuPage == 3)
|
|
|
|
nandemuPage = 1;
|
|
|
|
else
|
|
|
|
++nandemuPage;
|
|
|
|
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED)
|
|
|
|
m_btnMgr.click(m_nandemuBtnPageP);
|
|
|
|
_showNandEmu();
|
|
|
|
}
|
|
|
|
else if((BTN_HOME_PRESSED || BTN_B_PRESSED) && !m_thrdWorking)
|
|
|
|
break;
|
|
|
|
else if(BTN_UP_PRESSED && !m_thrdWorking)
|
|
|
|
m_btnMgr.up();
|
|
|
|
else if(BTN_DOWN_PRESSED && !m_thrdWorking)
|
|
|
|
m_btnMgr.down();
|
|
|
|
else if(BTN_A_PRESSED)
|
|
|
|
{
|
|
|
|
if(m_btnMgr.selected(m_nandemuBtnBack))
|
|
|
|
{
|
|
|
|
m_cfg.save();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(nandemuPage == 1)
|
|
|
|
{
|
|
|
|
if(m_btnMgr.selected(m_configBtn1P) || m_btnMgr.selected(m_configBtn1M))
|
|
|
|
{
|
|
|
|
direction = m_btnMgr.selected(m_configBtn1P) ? 1 : -1;
|
|
|
|
curEmuNand = loopNum(curEmuNand + direction, emuNands.size());
|
|
|
|
m_cfg.setString(CHANNEL_DOMAIN, "current_emunand", emuNands[curEmuNand]);
|
2022-09-07 20:39:22 +02:00
|
|
|
m_btnMgr.setText(m_configLbl1Val, emuNands[curEmuNand]);
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn2P) || m_btnMgr.selected(m_configBtn2M))
|
|
|
|
{
|
|
|
|
direction = m_btnMgr.selected(m_configBtn2P) ? 1 : -1;
|
|
|
|
m_cfg.setInt(CHANNEL_DOMAIN, "emulation", loopNum(m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0) + direction, ARRAY_SIZE(CMenu::_NandEmu)));
|
2022-09-07 20:39:22 +02:00
|
|
|
int i = min(max(0, m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0)), (int)ARRAY_SIZE(CMenu::_NandEmu) - 1);
|
|
|
|
m_btnMgr.setText(m_configLbl2Val, _t(CMenu::_NandEmu[i].id, CMenu::_NandEmu[i].text));
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn3P) || m_btnMgr.selected(m_configBtn3M))
|
|
|
|
{
|
|
|
|
direction = m_btnMgr.selected(m_configBtn3P) ? 1 : -1;
|
|
|
|
curSavesNand = loopNum(curSavesNand + direction, savesNands.size());
|
|
|
|
m_cfg.setString(WII_DOMAIN, "current_save_emunand", savesNands[curSavesNand]);
|
2022-09-07 20:39:22 +02:00
|
|
|
m_btnMgr.setText(m_configLbl3Val, savesNands[curSavesNand]);
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn4P) || m_btnMgr.selected(m_configBtn4M))
|
|
|
|
{
|
|
|
|
direction = m_btnMgr.selected(m_configBtn4P) ? 1 : -1;
|
|
|
|
m_cfg.setInt(WII_DOMAIN, "save_emulation", loopNum(m_cfg.getInt(WII_DOMAIN, "save_emulation", 0) + direction, ARRAY_SIZE(CMenu::_GlobalSaveEmu)));
|
2022-09-07 20:39:22 +02:00
|
|
|
int i = min(max(0, m_cfg.getInt(WII_DOMAIN, "save_emulation", 0)), (int)ARRAY_SIZE(CMenu::_GlobalSaveEmu) - 1);
|
|
|
|
m_btnMgr.setText(m_configLbl4Val, _t(CMenu::_GlobalSaveEmu[i].id, CMenu::_GlobalSaveEmu[i].text));
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nandemuPage == 2)
|
|
|
|
{
|
|
|
|
if(m_btnMgr.selected(m_configBtn1) || m_btnMgr.selected(m_configBtn2) || m_btnMgr.selected(m_configBtn3))
|
|
|
|
{
|
|
|
|
m_nanddump = m_btnMgr.selected(m_configBtn3) ? true : false;
|
|
|
|
m_saveall = m_btnMgr.selected(m_configBtn1) ? true : false;
|
|
|
|
|
|
|
|
m_btnMgr.hide(m_nandemuBtnBack);
|
|
|
|
_hideNandEmu(true);
|
|
|
|
int emuPart = _FindEmuPart(!m_nanddump, true);
|
|
|
|
if(emuPart < 0)
|
|
|
|
{
|
2022-07-14 00:11:44 +02:00
|
|
|
_error(_t("cfgne8", L"No valid FAT partition found for NAND Emulation!"));
|
2022-07-07 00:34:55 +02:00
|
|
|
_showNandEmu();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_btnMgr.show(m_nandemuLblTitle);
|
|
|
|
m_btnMgr.show(m_nandfilePBar);
|
|
|
|
m_btnMgr.show(m_nandemuPBar);
|
|
|
|
m_btnMgr.show(m_nandfileLblMessage);
|
|
|
|
m_btnMgr.show(m_nandemuLblMessage);
|
|
|
|
m_btnMgr.show(m_nandfileLblDialog);
|
|
|
|
m_btnMgr.show(m_nandemuLblDialog);
|
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, _t("cfgne11", L"Overall Progress:"));
|
|
|
|
if(m_nanddump)
|
|
|
|
{
|
|
|
|
ExtNand = emuNands[curEmuNand];// set for later to refresh game list
|
|
|
|
m_btnMgr.setText(m_nandemuLblTitle, _t("cfgne12", L"NAND Extractor"));
|
|
|
|
}
|
|
|
|
else // saves dump
|
|
|
|
{
|
|
|
|
//ExtNand = savesNands[curSavesNand];
|
|
|
|
m_btnMgr.setText(m_nandemuLblTitle, _t("cfgne13", L"Game Save Extractor"));
|
|
|
|
}
|
|
|
|
m_thrdStop = false;
|
|
|
|
m_thrdProgress = 0.f;
|
|
|
|
m_thrdWorking = true;
|
|
|
|
LWP_CreateThread(&thread, _NandDumper, this, 0, 32768, 40);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn4))
|
|
|
|
{
|
|
|
|
_hideNandEmu();
|
|
|
|
_wadExplorer();
|
|
|
|
nandemuPage = 1;
|
|
|
|
_showNandEmu();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nandemuPage == 3)
|
|
|
|
{
|
|
|
|
if(m_btnMgr.selected(m_configBtn1P) || m_btnMgr.selected(m_configBtn1M))
|
|
|
|
{
|
|
|
|
direction = m_btnMgr.selected(m_configBtn1P) ? 1 : -1;
|
2022-11-29 22:39:12 +01:00
|
|
|
_setPartition(direction, m_cfg.getInt(WII_DOMAIN, "savepartition"), COVERFLOW_NONE);
|
2022-12-10 22:10:29 +01:00
|
|
|
m_cfg.setInt(WII_DOMAIN, "savepartition", currentPartition);
|
|
|
|
m_btnMgr.setText(m_configLbl1Val, upperCase(DeviceName[currentPartition]));
|
2022-07-07 00:34:55 +02:00
|
|
|
_getEmuNands();// refresh emunands in case the partition was changed
|
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn2))
|
|
|
|
{
|
|
|
|
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand_config", !m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_config"));
|
2022-09-07 20:39:22 +02:00
|
|
|
m_btnMgr.setText(m_configBtn2, m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_config", false) ? _t("on", L"On") : _t("off", L"Off"));
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
else if(m_btnMgr.selected(m_configBtn3))
|
|
|
|
{
|
|
|
|
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand_miis", !m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_miis"));
|
2022-09-07 20:39:22 +02:00
|
|
|
m_btnMgr.setText(m_configBtn3, m_cfg.getBool(CHANNEL_DOMAIN, "real_nand_miis", false) ? _t("on", L"On") : _t("off", L"Off"));
|
2022-07-07 00:34:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(m_thrdMessageAdded)
|
|
|
|
{
|
|
|
|
LockMutex lock(m_mutex);
|
|
|
|
m_thrdMessageAdded = false;
|
|
|
|
if(!m_thrdMessage.empty())
|
|
|
|
m_btnMgr.setText(m_nandfileLblDialog, m_thrdMessage);
|
|
|
|
m_btnMgr.setProgress(m_nandfilePBar, m_fileProgress);
|
|
|
|
m_btnMgr.setProgress(m_nandemuPBar, m_thrdProgress);
|
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, wfmt(_fmt("fileprogress", L"%d / %dKB"), m_fileprog/0x400, m_filesize/0x400));
|
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, wfmt(_fmt("dumpprogress", L"%i%%"), (int)(m_thrdProgress*100.f)));
|
|
|
|
|
|
|
|
if(!m_thrdWorking)
|
|
|
|
{
|
|
|
|
if(m_sgdump)
|
|
|
|
m_btnMgr.setText(m_nandfinLblDialog, wfmt(_fmt("cfgne14", L"Extracted: %d saves / %d files / %d folders"), m_nandexentry, m_filesdone, m_foldersdone));
|
|
|
|
else
|
|
|
|
m_btnMgr.setText(m_nandfinLblDialog, wfmt(_fmt("cfgne15", L"Extracted: %d files / %d folders"), m_filesdone, m_foldersdone));
|
2023-03-16 23:45:51 +01:00
|
|
|
wstringEx total_size;
|
2022-07-07 00:34:55 +02:00
|
|
|
if(m_dumpsize/0x400 > 0x270f)
|
2023-03-16 23:45:51 +01:00
|
|
|
total_size = wfmt(_fmt("cfgne16", L"Total size: %uMB (%d blocks)"), (m_dumpsize/0x100000), (m_dumpsize/0x8000)>>2);
|
2022-07-07 00:34:55 +02:00
|
|
|
else
|
2023-03-16 23:45:51 +01:00
|
|
|
total_size = wfmt(_fmt("cfgne17", L"Total size: %uKB (%d blocks)"), (m_dumpsize/0x400), (m_dumpsize/0x8000)>>2);
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, total_size);
|
2022-07-07 00:34:55 +02:00
|
|
|
m_btnMgr.show(m_nandemuBtnBack);
|
|
|
|
m_btnMgr.show(m_nandfinLblDialog);
|
|
|
|
while(!m_exit)
|
|
|
|
{
|
|
|
|
_mainLoopCommon();
|
|
|
|
if(BTN_HOME_PRESSED || BTN_B_PRESSED || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnBack)))
|
|
|
|
{
|
|
|
|
_hideNandEmu();
|
2023-03-12 23:36:25 +01:00
|
|
|
m_btnMgr.hide(m_nandfileLblDialog);
|
|
|
|
m_btnMgr.hide(m_nandemuLblDialog);
|
|
|
|
m_btnMgr.hide(m_nandfinLblDialog);
|
2022-07-07 00:34:55 +02:00
|
|
|
nandemuPage = 1;
|
|
|
|
_showNandEmu();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_hideNandEmu();
|
|
|
|
_FullNandCheck();
|
|
|
|
/* if changed emunand choice or emunand is the new one extracted */
|
|
|
|
if(emuNand != m_cfg.getString(CHANNEL_DOMAIN, "current_emunand") || emuNand == ExtNand)
|
|
|
|
{
|
|
|
|
m_cfg.setBool(CHANNEL_DOMAIN, "update_cache", true);
|
|
|
|
if(m_current_view & COVERFLOW_CHANNEL)
|
|
|
|
m_refreshGameList = true;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenu::_initNandEmuMenu()
|
|
|
|
{
|
|
|
|
m_nandemuBg = _texture("NANDEMU/BG", "texture", theme.bg, false);
|
|
|
|
|
|
|
|
_addUserLabels(m_nandemuLblUser, ARRAY_SIZE(m_nandemuLblUser), "NANDEMU");
|
|
|
|
m_nandemuLblTitle = _addLabel("NANDEMU/TITLE", theme.titleFont, L"", 0, 10, 640, 60, theme.titleFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE);
|
|
|
|
m_nandemuBtnBack = _addButton("NANDEMU/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 48, theme.btnFontColor);
|
|
|
|
m_nandemuLblPage = _addLabel("NANDEMU/PAGE_BTN", theme.btnFont, L"", 68, 400, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
|
|
|
m_nandemuBtnPageM = _addPicButton("NANDEMU/PAGE_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 20, 400, 48, 48);
|
|
|
|
m_nandemuBtnPageP = _addPicButton("NANDEMU/PAGE_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 172, 400, 48, 48);
|
|
|
|
|
|
|
|
m_nandfilePBar = _addProgressBar("NANDEMU/FILEPROGRESS_BAR", 40, 80, 560, 20);
|
|
|
|
m_nandfileLblMessage = _addLabel("NANDEMU/FMESSAGE", theme.lblFont, L"", 40, 110, 560, 100, theme.lblFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_TOP);
|
|
|
|
m_nandfileLblDialog = _addLabel("NANDEMU/FDIALOG", theme.lblFont, L"", 40, 60, 560, 200, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
|
|
|
m_nandemuPBar = _addProgressBar("NANDEMU/PROGRESS_BAR", 40, 220, 560, 20);
|
|
|
|
m_nandemuLblMessage = _addLabel("NANDEMU/MESSAGE", theme.lblFont, L"", 40, 280, 560, 100, theme.lblFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_TOP);
|
|
|
|
m_nandemuLblDialog = _addLabel("NANDEMU/DIALOG", theme.lblFont, L"", 40, 190, 560, 200, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
|
|
|
m_nandfinLblDialog = _addLabel("NANDEMU/FINDIALOG", theme.lblFont, L"", 40, 120, 560, 200, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
|
|
|
|
|
|
|
_setHideAnim(m_nandemuLblTitle, "NANDEMU/TITLE", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandemuBtnBack, "NANDEMU/BACK_BTN", 0, 0, 1.f, -1.f);
|
|
|
|
_setHideAnim(m_nandemuLblPage, "NANDEMU/PAGE_BTN", 0, 0, 1.f, -1.f);
|
|
|
|
_setHideAnim(m_nandemuBtnPageM, "NANDEMU/PAGE_MINUS", 0, 0, 1.f, -1.f);
|
|
|
|
_setHideAnim(m_nandemuBtnPageP, "NANDEMU/PAGE_PLUS", 0, 0, 1.f, -1.f);
|
|
|
|
|
|
|
|
_setHideAnim(m_nandfileLblMessage, "NANDEMU/FMESSAGE", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandemuLblMessage, "NANDEMU/MESSAGE", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandfileLblDialog, "NANDEMU/FDIALOG", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandfinLblDialog, "NANDEMU/FINDIALOG", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandemuLblDialog, "NANDEMU/DIALOG", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandfilePBar, "NANDEMU/FILEPROGRESS_BAR", 0, 0, -2.f, 0.f);
|
|
|
|
_setHideAnim(m_nandemuPBar, "NANDEMU/PROGRESS_BAR", 0, 0, -2.f, 0.f);
|
|
|
|
|
|
|
|
_hideNandEmu(true);
|
|
|
|
_textNandEmu();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMenu::_textNandEmu(void)
|
|
|
|
{
|
|
|
|
m_btnMgr.setText(m_nandemuBtnBack, _t("cfgne7", L"Back"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-11 00:56:44 +01:00
|
|
|
void CMenu::_listEmuNands(const char *path, vector<string> &nands)
|
2016-04-21 02:05:28 +02:00
|
|
|
{
|
|
|
|
DIR *d;
|
|
|
|
struct dirent *dir;
|
2021-11-11 00:56:44 +01:00
|
|
|
nands.clear();
|
2018-07-09 16:53:35 +02:00
|
|
|
bool add_def = true;
|
2016-04-21 02:05:28 +02:00
|
|
|
|
|
|
|
d = opendir(path);
|
|
|
|
if(d != 0)
|
|
|
|
{
|
|
|
|
while((dir = readdir(d)) != 0)
|
|
|
|
{
|
|
|
|
if(dir->d_name[0] == '.')
|
|
|
|
continue;
|
|
|
|
if(dir->d_type == DT_DIR)
|
|
|
|
{
|
2021-11-11 00:56:44 +01:00
|
|
|
nands.push_back(dir->d_name);
|
2018-07-09 16:53:35 +02:00
|
|
|
if(strlen(dir->d_name) == 7 && strcasecmp(dir->d_name, "default") == 0)
|
|
|
|
add_def = false;
|
2016-04-21 02:05:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
}
|
2021-11-11 00:56:44 +01:00
|
|
|
else
|
|
|
|
return;
|
2018-07-09 16:53:35 +02:00
|
|
|
if(add_def)
|
2021-11-11 00:56:44 +01:00
|
|
|
nands.push_back("default");
|
|
|
|
sort(nands.begin(), nands.end());
|
2016-04-21 02:05:28 +02:00
|
|
|
}
|
|
|
|
|
2021-11-11 00:56:44 +01:00
|
|
|
void CMenu::_getEmuNands(void)
|
2016-05-15 02:29:16 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
u8 i;
|
|
|
|
string emuNand = m_cfg.getString(CHANNEL_DOMAIN, "current_emunand", "default");
|
2021-11-11 00:56:44 +01:00
|
|
|
int emuPart = m_cfg.getInt(CHANNEL_DOMAIN, "partition", -1);
|
2017-09-22 00:03:41 +02:00
|
|
|
string savesNand = m_cfg.getString(WII_DOMAIN, "current_save_emunand", "default");
|
2021-11-11 00:56:44 +01:00
|
|
|
int savesPart = m_cfg.getInt(WII_DOMAIN, "savepartition", -1);
|
2017-09-22 00:03:41 +02:00
|
|
|
|
2021-11-11 00:56:44 +01:00
|
|
|
/* emu Nands */
|
2019-03-27 17:45:43 +01:00
|
|
|
_listEmuNands(fmt("%s:/%s", DeviceName[emuPart], emu_nands_dir), emuNands);
|
2021-11-11 00:56:44 +01:00
|
|
|
|
|
|
|
if(emuNands.empty())// in case device has been temporarily disconnected
|
|
|
|
emuNands.push_back(emuNand);
|
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
curEmuNand = 0;
|
|
|
|
for(i = 0; i < emuNands.size(); ++i)// find current emunand folder
|
|
|
|
{
|
|
|
|
if(emuNands[i] == emuNand)
|
|
|
|
{
|
|
|
|
curEmuNand = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(i == emuNands.size())// didn't find emunand folder so set to default
|
2016-05-15 02:29:16 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
for(i = 0; i < emuNands.size(); ++i)
|
|
|
|
{
|
|
|
|
if(emuNands[i] == "default")
|
|
|
|
{
|
|
|
|
curEmuNand = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-05-15 02:29:16 +02:00
|
|
|
}
|
2021-11-11 00:56:44 +01:00
|
|
|
|
|
|
|
/* saves Nands */
|
2017-09-22 00:03:41 +02:00
|
|
|
_listEmuNands(fmt("%s:/%s", DeviceName[savesPart], emu_nands_dir), savesNands);
|
2021-11-11 00:56:44 +01:00
|
|
|
|
|
|
|
if(savesNands.empty())
|
|
|
|
savesNands.push_back(savesNand);
|
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
curSavesNand = 0;
|
|
|
|
for(i = 0; i < savesNands.size(); ++i)// find current savesnand folder
|
2016-05-15 02:29:16 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
if(savesNands[i] == savesNand)
|
|
|
|
{
|
|
|
|
curSavesNand = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(i == savesNands.size())// didn't find savesnand folder set to default
|
|
|
|
{
|
|
|
|
for(i = 0; i < savesNands.size(); ++i)
|
2016-05-15 02:29:16 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
if(savesNands[i] == "default")
|
|
|
|
{
|
|
|
|
curSavesNand = i;
|
|
|
|
break;
|
|
|
|
}
|
2016-05-15 02:29:16 +02:00
|
|
|
}
|
2017-09-22 00:03:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-11 00:56:44 +01:00
|
|
|
/* This checks if nand emulation is set to Full */
|
|
|
|
/* if is then it copies SYSCONF, setting.txt, and RFL_DB.dat only if they don't already exist */
|
|
|
|
/* this is helpful if you use a modmii created nand, wiiflow dumped nand will already have these files */
|
|
|
|
/* if you wish to overwrite these files then use the real nand mii's and config options */
|
2017-09-22 00:03:41 +02:00
|
|
|
void CMenu::_FullNandCheck(void)
|
|
|
|
{
|
|
|
|
for(u8 i = 0; i < 2; i++)
|
|
|
|
{
|
|
|
|
int emulate_mode;
|
2018-07-09 16:53:35 +02:00
|
|
|
if(i == EMU_NAND)
|
2022-02-07 14:19:27 +01:00
|
|
|
emulate_mode = m_cfg.getInt(CHANNEL_DOMAIN, "emulation");// partial by default
|
2016-05-15 02:29:16 +02:00
|
|
|
else
|
2022-02-07 14:19:27 +01:00
|
|
|
emulate_mode = m_cfg.getInt(WII_DOMAIN, "save_emulation");// off by default
|
2018-07-09 16:53:35 +02:00
|
|
|
if((i == EMU_NAND && emulate_mode == 1) || (i == SAVES_NAND && emulate_mode == 2))//full
|
2016-11-07 16:06:00 +01:00
|
|
|
{
|
2021-11-11 00:56:44 +01:00
|
|
|
int emuPart = _FindEmuPart(i, false);
|
2017-09-22 00:03:41 +02:00
|
|
|
if(emuPart < 0)
|
|
|
|
continue;
|
|
|
|
bool need_config = false;
|
|
|
|
bool need_miis = false;
|
2018-06-06 23:56:21 +02:00
|
|
|
const char *emuPath = NandHandle.Get_NandPath();
|
|
|
|
|
|
|
|
char basepath[MAX_FAT_PATH];
|
|
|
|
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[emuPart], emuPath);
|
|
|
|
|
|
|
|
char testpath[MAX_FAT_PATH + 42];
|
2017-09-22 00:03:41 +02:00
|
|
|
|
2022-02-07 14:19:27 +01:00
|
|
|
//check config file - time and date, video settings, etc...
|
2018-06-06 23:56:21 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/shared2/sys/SYSCONF", basepath);
|
|
|
|
if(!fsop_FileExist(testpath))
|
2017-09-22 00:03:41 +02:00
|
|
|
need_config = true;
|
2018-06-06 23:56:21 +02:00
|
|
|
|
2022-02-07 14:19:27 +01:00
|
|
|
// system info like model and serial numbers, not real important. modmii creates this file.
|
2018-06-06 23:56:21 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/title/00000001/00000002/data/setting.txt", basepath);
|
|
|
|
if(!fsop_FileExist(testpath))
|
2017-09-22 00:03:41 +02:00
|
|
|
need_config = true;
|
2018-06-06 23:56:21 +02:00
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
// Check Mii's
|
2018-06-06 23:56:21 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/shared2/menu/FaceLib/RFL_DB.dat", basepath);
|
|
|
|
if(!fsop_FileExist(testpath))
|
2017-09-22 00:03:41 +02:00
|
|
|
need_miis = true;
|
|
|
|
|
|
|
|
NandHandle.PreNandCfg(need_miis, need_config);//copy to emunand if needed
|
2016-11-07 16:06:00 +01:00
|
|
|
}
|
2016-05-15 02:29:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
int CMenu::_FindEmuPart(bool savesnand, bool skipchecks)
|
2016-06-20 23:03:40 +02:00
|
|
|
{
|
2016-11-07 16:06:00 +01:00
|
|
|
int emuPart;
|
2018-11-09 23:09:07 +01:00
|
|
|
char tmpPath[32];
|
|
|
|
tmpPath[31] = '\0';
|
2016-11-07 16:06:00 +01:00
|
|
|
if(savesnand)
|
2016-06-20 23:03:40 +02:00
|
|
|
{
|
2016-11-07 16:06:00 +01:00
|
|
|
emuPart = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
2018-11-12 21:38:37 +01:00
|
|
|
strncpy(tmpPath, fmt("/%s/%s", emu_nands_dir, m_cfg.getString(WII_DOMAIN, "current_save_emunand").c_str()), sizeof(tmpPath) - 1);
|
2016-06-20 23:03:40 +02:00
|
|
|
}
|
2012-06-07 02:34:47 +02:00
|
|
|
else
|
|
|
|
{
|
2016-11-07 16:06:00 +01:00
|
|
|
emuPart = m_cfg.getInt(CHANNEL_DOMAIN, "partition");
|
2018-11-12 21:38:37 +01:00
|
|
|
strncpy(tmpPath, fmt("/%s/%s", emu_nands_dir, m_cfg.getString(CHANNEL_DOMAIN, "current_emunand").c_str()), sizeof(tmpPath) - 1);
|
2012-06-07 02:34:47 +02:00
|
|
|
}
|
2018-07-09 16:53:35 +02:00
|
|
|
if(!DeviceHandle.PartitionUsableForNandEmu(emuPart))//check if device is mounted and partition is FAT
|
2016-06-20 23:03:40 +02:00
|
|
|
return -1;
|
2017-09-22 00:03:41 +02:00
|
|
|
else if((skipchecks || _TestEmuNand(emuPart, tmpPath, false)))//check if emunand folder exist
|
2016-06-20 23:03:40 +02:00
|
|
|
{
|
|
|
|
NandHandle.SetNANDEmu(emuPart);
|
|
|
|
NandHandle.SetPaths(tmpPath, DeviceName[emuPart]);
|
|
|
|
return emuPart;
|
|
|
|
}
|
|
|
|
return -2;
|
2012-06-07 02:34:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CMenu::_TestEmuNand(int epart, const char *path, bool indept)
|
|
|
|
{
|
|
|
|
char basepath[64];
|
|
|
|
char testpath[MAX_FAT_PATH];
|
|
|
|
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[epart], path);
|
2012-09-10 00:38:42 +02:00
|
|
|
|
2012-12-22 23:28:58 +01:00
|
|
|
DIR *d = opendir(basepath);
|
2012-06-07 02:34:47 +02:00
|
|
|
if(!d)
|
2012-09-10 00:38:42 +02:00
|
|
|
return false;
|
2012-06-07 02:34:47 +02:00
|
|
|
else
|
|
|
|
closedir(d);
|
2012-12-22 23:28:58 +01:00
|
|
|
|
2012-06-07 02:34:47 +02:00
|
|
|
if(indept)
|
|
|
|
{
|
|
|
|
// Check Wiimotes && Region
|
2016-04-21 02:05:28 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/shared2/sys/SYSCONF", basepath);
|
2012-06-07 07:14:51 +02:00
|
|
|
if(!fsop_FileExist(testpath))
|
2012-09-10 00:38:42 +02:00
|
|
|
return false;
|
2016-04-21 02:05:28 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/title/00000001/00000002/data/setting.txt", basepath);
|
2012-06-07 07:14:51 +02:00
|
|
|
if(!fsop_FileExist(testpath))
|
2012-09-10 00:38:42 +02:00
|
|
|
return false;
|
2012-06-07 02:34:47 +02:00
|
|
|
// Check Mii's
|
2016-04-21 02:05:28 +02:00
|
|
|
snprintf(testpath, sizeof(testpath), "%s/shared2/menu/FaceLib/RFL_DB.dat", basepath);
|
2012-06-07 07:14:51 +02:00
|
|
|
if(!fsop_FileExist(testpath))
|
2012-09-10 00:38:42 +02:00
|
|
|
return false;
|
2012-06-07 02:34:47 +02:00
|
|
|
}
|
2012-09-10 00:38:42 +02:00
|
|
|
return true;
|
2012-06-07 02:34:47 +02:00
|
|
|
}
|
|
|
|
|
2016-06-20 23:03:40 +02:00
|
|
|
static bool _saveExists(const char *path)
|
|
|
|
{
|
|
|
|
DIR *d = opendir(path);
|
|
|
|
if(!d)
|
|
|
|
return false;
|
|
|
|
else
|
2012-08-26 17:20:51 +02:00
|
|
|
{
|
2016-06-20 23:03:40 +02:00
|
|
|
closedir(d);
|
|
|
|
return true;
|
2012-06-07 02:34:47 +02:00
|
|
|
}
|
|
|
|
}
|
2012-05-11 01:38:34 +02:00
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
bool CMenu::_checkSave(string id, int nand_type)
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
|
|
|
int savePath = id.c_str()[0] << 24 | id.c_str()[1] << 16 | id.c_str()[2] << 8 | id.c_str()[3];
|
2018-07-09 16:53:35 +02:00
|
|
|
if(nand_type == REAL_NAND)
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
2012-12-22 23:28:58 +01:00
|
|
|
u32 temp = 0;
|
2012-11-18 14:40:26 +01:00
|
|
|
if(ISFS_ReadDir(fmt("/title/00010000/%08x", savePath), NULL, &temp) < 0)
|
|
|
|
if(ISFS_ReadDir(fmt("/title/00010004/%08x", savePath), NULL, &temp) < 0)
|
2012-05-11 01:38:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
2018-07-09 16:53:35 +02:00
|
|
|
else // SAVES_NAND
|
2012-12-22 23:28:58 +01:00
|
|
|
{
|
2016-11-07 16:06:00 +01:00
|
|
|
int emuPartition = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
2017-05-15 19:50:24 +02:00
|
|
|
const char *emuPath = fmt("/%s/%s", emu_nands_dir, m_cfg.getString(WII_DOMAIN, "current_save_emunand").c_str());
|
-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
|
|
|
if(emuPartition < 0 || emuPath == NULL)
|
2012-05-11 01:38:34 +02:00
|
|
|
return false;
|
|
|
|
struct stat fstat;
|
-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
|
|
|
if((stat(fmt("%s:%s/title/00010000/%08x", DeviceName[emuPartition], emuPath, savePath), &fstat) != 0)
|
|
|
|
&& (stat(fmt("%s:%s/title/00010004/%08x", DeviceName[emuPartition], emuPath, savePath), &fstat) != 0))
|
2012-05-11 01:38:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
void CMenu::_setDumpMsg(const wstringEx &msg, float totprog, float fileprog)
|
|
|
|
{
|
|
|
|
if(m_thrdStop) return;
|
|
|
|
if(msg != L"...") m_thrdMessage = msg;
|
|
|
|
m_thrdMessageAdded = true;
|
|
|
|
m_thrdProgress = totprog;
|
|
|
|
m_fileProgress = fileprog;
|
|
|
|
}
|
|
|
|
|
2012-12-27 21:22:40 +01:00
|
|
|
void CMenu::_ShowProgress(int dumpstat, int dumpprog, int filesize, int fileprog, int files, int folders, const char *tmess, void *user_data)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
|
|
|
CMenu &m = *(CMenu *)user_data;
|
|
|
|
m.m_progress = dumpprog == 0 ? 0.f : (float)dumpstat / (float)dumpprog;
|
|
|
|
m.m_fprogress = filesize == 0 ? 0.f : (float)fileprog / (float)filesize;
|
|
|
|
m.m_fileprog = fileprog;
|
|
|
|
m.m_filesize = filesize;
|
|
|
|
m.m_filesdone = files;
|
|
|
|
m.m_foldersdone = folders;
|
|
|
|
LWP_MutexLock(m.m_mutex);
|
2012-06-08 15:05:21 +02:00
|
|
|
if(m_nandext)
|
2012-05-03 01:08:11 +02:00
|
|
|
m._setDumpMsg(wfmt(m._fmt("cfgne9", L"Current file: %s"), tmess), m.m_progress, m.m_fprogress);
|
|
|
|
else
|
|
|
|
m._setDumpMsg(L"...", m.m_progress, m.m_fprogress);
|
|
|
|
LWP_MutexUnlock(m.m_mutex);
|
|
|
|
}
|
|
|
|
|
2022-07-07 00:34:55 +02:00
|
|
|
int CMenu::_FlashGameSave(string gameId)
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
2018-07-09 16:53:35 +02:00
|
|
|
if(_FindEmuPart(SAVES_NAND, false) < 0)// if savesnand folder not found
|
2017-09-22 00:03:41 +02:00
|
|
|
return 0;
|
2012-05-11 01:38:34 +02:00
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
if(!_checkSave(gameId, SAVES_NAND))// if save not on saves emunand
|
2012-05-11 01:38:34 +02:00
|
|
|
return 0;
|
2012-12-22 23:28:58 +01:00
|
|
|
|
2012-05-11 01:38:34 +02:00
|
|
|
lwp_t thread = 0;
|
|
|
|
m_thrdStop = false;
|
|
|
|
m_thrdMessageAdded = false;
|
|
|
|
m_nandext = false;
|
|
|
|
m_saveExtGameId = gameId;
|
2018-07-09 16:53:35 +02:00
|
|
|
|
|
|
|
m_btnMgr.show(m_nandemuLblTitle);
|
|
|
|
m_btnMgr.show(m_nandfilePBar);
|
|
|
|
m_btnMgr.show(m_nandemuPBar);
|
|
|
|
m_btnMgr.show(m_nandfileLblMessage);
|
|
|
|
m_btnMgr.show(m_nandemuLblMessage);
|
|
|
|
m_btnMgr.show(m_nandfileLblDialog);
|
|
|
|
m_btnMgr.show(m_nandemuLblDialog);
|
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, _t("cfgne11", L"Overall Progress:"));
|
|
|
|
m_btnMgr.setText(m_nandemuLblTitle, _t("cfgne28", L"Game Save Flasher"));
|
|
|
|
m_thrdProgress = 0.f;
|
|
|
|
m_thrdWorking = true;
|
|
|
|
LWP_CreateThread(&thread, _NandFlasher, this, 0, 32768, 40);
|
|
|
|
|
|
|
|
SetupInput();
|
2012-05-11 01:38:34 +02:00
|
|
|
|
2012-09-09 20:35:15 +02:00
|
|
|
while(!m_exit)
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
2012-09-09 20:35:15 +02:00
|
|
|
_mainLoopCommon();
|
2017-09-22 00:03:41 +02:00
|
|
|
if(!m_thrdWorking && (BTN_HOME_PRESSED || BTN_B_PRESSED || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnBack))))
|
|
|
|
break;
|
2012-05-11 01:38:34 +02:00
|
|
|
|
|
|
|
if(m_thrdMessageAdded)
|
|
|
|
{
|
|
|
|
LockMutex lock(m_mutex);
|
|
|
|
m_thrdMessageAdded = false;
|
2016-12-01 01:05:39 +01:00
|
|
|
if(!m_thrdMessage.empty())
|
2012-05-11 01:38:34 +02:00
|
|
|
m_btnMgr.setText(m_nandfileLblDialog, m_thrdMessage);
|
|
|
|
m_btnMgr.setProgress(m_nandfilePBar, m_fileProgress);
|
|
|
|
m_btnMgr.setProgress(m_nandemuPBar, m_thrdProgress);
|
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, wfmt(_fmt("fileprogress", L"%d / %dKB"), m_fileprog/0x400, m_filesize/0x400));
|
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, wfmt(_fmt("dumpprogress", L"%i%%"), (int)(m_thrdProgress*100.f)));
|
|
|
|
|
2016-12-01 01:05:39 +01:00
|
|
|
if(!m_thrdWorking)
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
|
|
|
m_btnMgr.setText(m_nandfinLblDialog, wfmt(_fmt("cfgne29", L"Flashed: %d saves / %d files / %d folders"), m_nandexentry, m_filesdone, m_foldersdone));
|
|
|
|
if(m_dumpsize/0x400 > 0x270f)
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, wfmt(_fmt("cfgne16", L"Total size: %uMB (%d blocks)"), (m_dumpsize/0x100000), (m_dumpsize/0x8000)>>2));
|
|
|
|
else
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, wfmt(_fmt("cfgne17", L"Total size: %uKB (%d blocks)"), (m_dumpsize/0x400), (m_dumpsize/0x8000)>>2));
|
2012-12-22 23:28:58 +01:00
|
|
|
|
2012-05-11 01:38:34 +02:00
|
|
|
m_btnMgr.show(m_nandemuBtnBack);
|
|
|
|
m_btnMgr.show(m_nandfinLblDialog);
|
|
|
|
}
|
|
|
|
}
|
2012-12-22 23:28:58 +01:00
|
|
|
}
|
2012-05-11 01:38:34 +02:00
|
|
|
_hideNandEmu();
|
2017-09-22 00:03:41 +02:00
|
|
|
return 1;
|
2012-05-11 01:38:34 +02:00
|
|
|
}
|
|
|
|
|
2022-07-07 00:34:55 +02:00
|
|
|
void * CMenu::_NandFlasher(void *obj)
|
|
|
|
{
|
|
|
|
CMenu &m = *(CMenu *)obj;
|
|
|
|
|
|
|
|
char source[MAX_FAT_PATH];
|
|
|
|
char dest[ISFS_MAXPATH];
|
|
|
|
|
|
|
|
int emuPartition = m._FindEmuPart(SAVES_NAND, true);
|
|
|
|
const char *emuPath = NandHandle.Get_NandPath();
|
|
|
|
|
|
|
|
const char *SaveGameID = m.m_saveExtGameId.c_str();
|
|
|
|
int flashID = SaveGameID[0] << 24 | SaveGameID[1] << 16 | SaveGameID[2] << 8 | SaveGameID[3];
|
|
|
|
|
|
|
|
/* we know it exist on emunand just need to figure out which folder */
|
|
|
|
if(_saveExists(fmt("%s:%s/title/00010000/%08x", DeviceName[emuPartition], emuPath, flashID)))
|
|
|
|
{
|
|
|
|
snprintf(source, sizeof(source), "%s:%s/title/00010000/%08x", DeviceName[emuPartition], emuPath, flashID);
|
|
|
|
snprintf(dest, sizeof(dest), "/title/00010000/%08x", flashID);
|
|
|
|
}
|
|
|
|
else //if(_saveExists(fmt("%s:%s/title/00010004/%08x", DeviceName[emuPartition], emuPath, flashID)))
|
|
|
|
{
|
|
|
|
snprintf(source, sizeof(source), "%s:%s/title/00010004/%08x", DeviceName[emuPartition], emuPath, flashID);
|
|
|
|
snprintf(dest, sizeof(dest), "/title/00010004/%08x", flashID);
|
|
|
|
}
|
|
|
|
NandHandle.ResetCounters();
|
|
|
|
m.m_nandexentry = 1;
|
|
|
|
m.m_dumpsize = NandHandle.CalcFlashSize(source, _ShowProgress, obj);
|
|
|
|
m_nandext = true;
|
|
|
|
NandHandle.FlashToNAND(source, dest, _ShowProgress, obj);
|
|
|
|
|
|
|
|
LWP_MutexLock(m.m_mutex);
|
|
|
|
m_btnMgr.hide(m_nandfilePBar);
|
|
|
|
m_btnMgr.hide(m_nandfileLblMessage);
|
|
|
|
m_btnMgr.hide(m_nandemuPBar);
|
|
|
|
m_btnMgr.hide(m_nandemuLblMessage);
|
|
|
|
m._setDumpMsg(m._t("cfgne30", L"Flashing save files finished!"), 1.f, 1.f);
|
|
|
|
LWP_MutexUnlock(m.m_mutex);
|
|
|
|
m.m_thrdWorking = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CMenu::_ExtractGameSave(string gameId)// called from game settings menu to extract a gamesave from real nand to savesnand
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2021-11-11 00:56:44 +01:00
|
|
|
if(!_checkSave(gameId, REAL_NAND))//if save not on real nand
|
|
|
|
return 0;
|
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
int emuPart = _FindEmuPart(SAVES_NAND, false);
|
|
|
|
if(emuPart == -1)// if savesnand partition unusable
|
2017-09-22 00:03:41 +02:00
|
|
|
return 0;
|
2018-07-09 16:53:35 +02:00
|
|
|
else if(emuPart == -2)// emunand folder not found so make it
|
2017-09-22 00:03:41 +02:00
|
|
|
{
|
2018-07-09 16:53:35 +02:00
|
|
|
emuPart = _FindEmuPart(SAVES_NAND, true);
|
|
|
|
const char *emuPath = NandHandle.Get_NandPath();
|
2017-09-22 00:03:41 +02:00
|
|
|
char basepath[MAX_FAT_PATH];
|
2018-07-09 16:53:35 +02:00
|
|
|
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[emuPart], emuPath);
|
2017-09-22 00:03:41 +02:00
|
|
|
NandHandle.CreatePath("%s/import", basepath);
|
|
|
|
NandHandle.CreatePath("%s/meta", basepath);
|
|
|
|
NandHandle.CreatePath("%s/shared1", basepath);
|
|
|
|
NandHandle.CreatePath("%s/shared2", basepath);
|
|
|
|
NandHandle.CreatePath("%s/sys", basepath);
|
|
|
|
NandHandle.CreatePath("%s/title", basepath);
|
|
|
|
NandHandle.CreatePath("%s/ticket", basepath);
|
|
|
|
NandHandle.CreatePath("%s/tmp", basepath);
|
2018-07-09 16:53:35 +02:00
|
|
|
}
|
2017-09-22 00:03:41 +02:00
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
lwp_t thread = 0;
|
|
|
|
m_thrdStop = false;
|
|
|
|
m_thrdMessageAdded = false;
|
2012-12-22 23:28:58 +01:00
|
|
|
m_nandext = false;
|
2017-09-22 00:03:41 +02:00
|
|
|
m_saveExtGameId = gameId;
|
|
|
|
bool finished = false;
|
2018-07-09 16:53:35 +02:00
|
|
|
m_nanddump = false;
|
|
|
|
|
|
|
|
m_btnMgr.show(m_nandemuLblTitle);
|
|
|
|
m_btnMgr.show(m_nandfilePBar);
|
|
|
|
m_btnMgr.show(m_nandemuPBar);
|
|
|
|
m_btnMgr.show(m_nandfileLblMessage);
|
|
|
|
m_btnMgr.show(m_nandemuLblMessage);
|
|
|
|
m_btnMgr.show(m_nandfileLblDialog);
|
|
|
|
m_btnMgr.show(m_nandemuLblDialog);
|
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, L"");
|
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, _t("cfgne11", L"Overall Progress:"));
|
|
|
|
m_btnMgr.setText(m_nandemuLblTitle, _t("cfgne13", L"Game Save Extractor"));
|
|
|
|
m_thrdProgress = 0.f;
|
|
|
|
m_thrdWorking = true;
|
|
|
|
LWP_CreateThread(&thread, _NandDumper, this, 0, 32768, 40);
|
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
SetupInput();
|
|
|
|
|
2012-09-09 20:35:15 +02:00
|
|
|
while(!m_exit)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2012-09-09 20:35:15 +02:00
|
|
|
_mainLoopCommon();
|
2018-07-09 16:53:35 +02:00
|
|
|
if(finished && (BTN_HOME_PRESSED || BTN_B_PRESSED || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnBack))))
|
2017-09-22 00:03:41 +02:00
|
|
|
break;
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
if(m_thrdMessageAdded)
|
|
|
|
{
|
|
|
|
LockMutex lock(m_mutex);
|
|
|
|
m_thrdMessageAdded = false;
|
2016-12-01 01:05:39 +01:00
|
|
|
if(!m_thrdMessage.empty())
|
2012-05-03 01:08:11 +02:00
|
|
|
m_btnMgr.setText(m_nandfileLblDialog, m_thrdMessage);
|
|
|
|
m_btnMgr.setProgress(m_nandfilePBar, m_fileProgress);
|
|
|
|
m_btnMgr.setProgress(m_nandemuPBar, m_thrdProgress);
|
2012-05-06 15:55:56 +02:00
|
|
|
m_btnMgr.setText(m_nandfileLblMessage, wfmt(_fmt("fileprogress", L"%d / %dKB"), m_fileprog/0x400, m_filesize/0x400));
|
2012-05-03 01:08:11 +02:00
|
|
|
m_btnMgr.setText(m_nandemuLblMessage, wfmt(_fmt("dumpprogress", L"%i%%"), (int)(m_thrdProgress*100.f)));
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2016-12-01 01:05:39 +01:00
|
|
|
if(!m_thrdWorking)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
finished = true;
|
2012-05-03 01:08:11 +02:00
|
|
|
m_btnMgr.setText(m_nandfinLblDialog, wfmt(_fmt("cfgne14", L"Extracted: %d saves / %d files / %d folders"), m_nandexentry, m_filesdone, m_foldersdone));
|
|
|
|
if(m_dumpsize/0x400 > 0x270f)
|
2012-05-06 14:59:09 +02:00
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, wfmt(_fmt("cfgne16", L"Total size: %uMB (%d blocks)"), (m_dumpsize/0x100000), (m_dumpsize/0x8000)>>2));
|
2012-05-03 01:08:11 +02:00
|
|
|
else
|
2012-05-06 14:59:09 +02:00
|
|
|
m_btnMgr.setText(m_nandemuLblDialog, wfmt(_fmt("cfgne17", L"Total size: %uKB (%d blocks)"), (m_dumpsize/0x400), (m_dumpsize/0x8000)>>2));
|
2012-05-03 01:08:11 +02:00
|
|
|
|
2012-05-11 01:38:34 +02:00
|
|
|
m_btnMgr.show(m_nandemuBtnBack);
|
|
|
|
m_btnMgr.show(m_nandfinLblDialog);
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
|
|
|
}
|
2012-12-22 23:28:58 +01:00
|
|
|
}
|
2012-05-03 01:08:11 +02:00
|
|
|
_hideNandEmu();
|
2017-09-22 00:03:41 +02:00
|
|
|
return 1;
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
|
|
|
|
2018-05-29 11:59:57 +02:00
|
|
|
void * CMenu::_NandDumper(void *obj)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
|
|
|
CMenu &m = *(CMenu *)obj;
|
2017-09-22 00:03:41 +02:00
|
|
|
|
2012-06-08 15:05:21 +02:00
|
|
|
m_nandext = false;
|
|
|
|
m_sgdump = false;
|
2012-05-03 01:08:11 +02:00
|
|
|
m.m_dumpsize = 0;
|
|
|
|
m.m_filesdone = 0;
|
|
|
|
m.m_foldersdone = 0;
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2012-10-15 21:16:14 +02:00
|
|
|
NandHandle.ResetCounters();
|
2017-09-22 00:03:41 +02:00
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
int emuPartition = m._FindEmuPart(!m_nanddump, true);
|
2018-06-06 23:56:21 +02:00
|
|
|
const char *emuPath = NandHandle.Get_NandPath();
|
2012-05-03 01:08:11 +02:00
|
|
|
char basepath[64];
|
2018-06-06 23:56:21 +02:00
|
|
|
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[emuPartition], emuPath);
|
2017-09-22 00:03:41 +02:00
|
|
|
/* create basepath in case it doesn't exist */
|
|
|
|
NandHandle.CreatePath("%s", basepath);
|
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
LWP_MutexLock(m.m_mutex);
|
2012-05-06 15:55:56 +02:00
|
|
|
m._setDumpMsg(m._t("cfgne27", L"Calculating space needed for extraction..."), 0.f, 0.f);
|
2012-05-03 01:08:11 +02:00
|
|
|
LWP_MutexUnlock(m.m_mutex);
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
if(m_nanddump)/* full nand dump */
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2012-10-15 21:16:14 +02:00
|
|
|
m.m_dumpsize = NandHandle.CalcDumpSpace("/", CMenu::_ShowProgress, obj);
|
2012-06-08 15:05:21 +02:00
|
|
|
m_nandext = true;
|
2012-10-15 21:16:14 +02:00
|
|
|
NandHandle.DoNandDump("/", basepath, CMenu::_ShowProgress, obj);
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
2017-09-22 00:03:41 +02:00
|
|
|
else /* gamesave(s) dump */
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2012-06-08 15:05:21 +02:00
|
|
|
bool missingOnly = !m_saveall;
|
2012-05-06 14:03:43 +02:00
|
|
|
vector<string> saveList;
|
2012-06-08 15:05:21 +02:00
|
|
|
m_sgdump = true;
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
if(m.m_saveExtGameId.empty())// if not a specified gamesave from game config menu or launching wii game
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2017-09-22 00:03:41 +02:00
|
|
|
/* extract all or missing gamesaves - main emunand settings menu */
|
2016-12-01 01:05:39 +01:00
|
|
|
LWP_MutexLock(m.m_mutex);
|
|
|
|
m._setDumpMsg(m._t("cfgne18", L"Listing game saves to extract..."), 0.f, 0.f);
|
|
|
|
LWP_MutexUnlock(m.m_mutex);
|
2012-05-03 01:08:11 +02:00
|
|
|
m.m_nandexentry = 0;
|
2016-06-20 23:03:40 +02:00
|
|
|
saveList.reserve(m.m_gameList.size());
|
|
|
|
for(u32 i = 0; i < m.m_gameList.size() && !m.m_thrdStop; ++i)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2016-12-01 01:05:39 +01:00
|
|
|
if(m.m_gameList[i].type == TYPE_WII_GAME)
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2016-06-20 23:03:40 +02:00
|
|
|
string id((const char *)m.m_gameList[i].id, 4);
|
|
|
|
|
2018-07-09 16:53:35 +02:00
|
|
|
if(!missingOnly || !m._checkSave(id, SAVES_NAND))// if all or the gamesave is not already on saves emunand
|
2012-05-03 01:08:11 +02:00
|
|
|
{
|
2018-07-09 16:53:35 +02:00
|
|
|
if(m._checkSave(id, REAL_NAND))// if save on real nand
|
2016-06-20 23:03:40 +02:00
|
|
|
{
|
|
|
|
m.m_nandexentry++;
|
|
|
|
saveList.push_back(id);
|
|
|
|
}
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
2012-05-06 14:59:09 +02:00
|
|
|
}
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
|
|
|
}
|
2017-09-22 00:03:41 +02:00
|
|
|
else /*one gamesave extract from game config menu or launching wii game */
|
2012-05-11 01:38:34 +02:00
|
|
|
{
|
|
|
|
m.m_nandexentry = 1;
|
2012-05-03 01:08:11 +02:00
|
|
|
saveList.push_back(m.m_saveExtGameId);
|
2012-05-11 01:38:34 +02:00
|
|
|
}
|
2012-05-03 01:08:11 +02:00
|
|
|
|
2017-09-22 00:03:41 +02:00
|
|
|
/* for loop to calculate SD or HDD space NanHandle will need for the actual savegame(s) dump */
|
2012-05-03 01:08:11 +02:00
|
|
|
for(u32 i = 0; i < saveList.size() && !m.m_thrdStop; ++i)
|
|
|
|
{
|
|
|
|
char source[ISFS_MAXPATH];
|
|
|
|
int savePath = saveList[i].c_str()[0] << 24 | saveList[i].c_str()[1] << 16 | saveList[i].c_str()[2] << 8 | saveList[i].c_str()[3];
|
2012-05-11 01:38:34 +02:00
|
|
|
snprintf(source, sizeof(source), "/title/00010000/%08x", savePath);
|
2018-07-09 16:53:35 +02:00
|
|
|
if(!m._checkSave(saveList[i], REAL_NAND))
|
2012-05-11 01:38:34 +02:00
|
|
|
snprintf(source, sizeof(source), "/title/00010004/%08x", savePath);
|
2012-06-08 15:05:21 +02:00
|
|
|
|
2012-10-15 21:16:14 +02:00
|
|
|
m.m_dumpsize = NandHandle.CalcDumpSpace(source, CMenu::_ShowProgress, obj);
|
2012-12-22 23:28:58 +01:00
|
|
|
}
|
2017-09-22 00:03:41 +02:00
|
|
|
/* for loop to do the actual savegame(s) dump */
|
2012-05-03 01:08:11 +02:00
|
|
|
for(u32 i = 0; i < saveList.size() && !m.m_thrdStop; ++i)
|
|
|
|
{
|
|
|
|
char source[ISFS_MAXPATH];
|
|
|
|
int savePath = saveList[i].c_str()[0] << 24 | saveList[i].c_str()[1] << 16 | saveList[i].c_str()[2] << 8 | saveList[i].c_str()[3];
|
2012-12-22 23:28:58 +01:00
|
|
|
snprintf(source, sizeof(source), "/title/00010000/%08x", savePath);
|
2018-07-09 16:53:35 +02:00
|
|
|
if(!m._checkSave(saveList[i], REAL_NAND))
|
2012-05-08 02:59:53 +02:00
|
|
|
snprintf(source, sizeof(source), "/title/00010004/%08x", savePath);
|
2012-06-08 15:05:21 +02:00
|
|
|
|
|
|
|
m_nandext = true;
|
2012-10-15 21:16:14 +02:00
|
|
|
NandHandle.DoNandDump(source, basepath, CMenu::_ShowProgress, obj);
|
2012-05-03 01:08:11 +02:00
|
|
|
}
|
|
|
|
}
|
2012-05-06 14:59:09 +02:00
|
|
|
|
2012-05-03 01:08:11 +02:00
|
|
|
LWP_MutexLock(m.m_mutex);
|
2012-12-21 20:51:22 +01:00
|
|
|
m_btnMgr.hide(m_nandfilePBar);
|
|
|
|
m_btnMgr.hide(m_nandfileLblMessage);
|
2016-12-01 01:05:39 +01:00
|
|
|
m_btnMgr.hide(m_nandemuPBar);
|
|
|
|
m_btnMgr.hide(m_nandemuLblMessage);
|
2012-05-03 01:08:11 +02:00
|
|
|
m._setDumpMsg(m._t("cfgne19", L"Extraction finished!"), 1.f, 1.f);
|
|
|
|
LWP_MutexUnlock(m.m_mutex);
|
2017-09-22 00:03:41 +02:00
|
|
|
m.m_thrdWorking = false;
|
2012-05-03 01:08:11 +02:00
|
|
|
return 0;
|
|
|
|
}
|