mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-23 19:59:16 +01:00
-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.
This commit is contained in:
parent
f72def02ba
commit
db8a2b137c
BIN
out/boot.dol
BIN
out/boot.dol
Binary file not shown.
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.1 MiB |
@ -32,7 +32,7 @@
|
||||
#include "loader/sys.h"
|
||||
#include "homebrew/homebrew.h"
|
||||
#include "memory/mem2.hpp"
|
||||
#include "network/FTP_Dir.hpp"
|
||||
//#include "network/FTP_Dir.hpp"
|
||||
#include "network/http.h"
|
||||
#include "plugin/crc32.h"
|
||||
|
||||
@ -157,7 +157,7 @@ void ShutdownBeforeExit(void)
|
||||
while(net_get_status() == -EBUSY)
|
||||
usleep(50);
|
||||
WiFiDebugger.Close();
|
||||
ftp_endTread();
|
||||
//ftp_endTread();
|
||||
net_deinit();
|
||||
networkInit = false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define APP_NAME "WiiFlow Lite"
|
||||
#define APP_VERSION "Beta 4.2.2"
|
||||
#define APP_VERSION "Beta 4.3.0"
|
||||
|
||||
#define APP_DATA_DIR "wiiflow"
|
||||
#define APPS_DIR "apps/wiiflow_lite"
|
||||
@ -25,7 +25,6 @@
|
||||
#define PLUGIN_DOMAIN "PLUGINS"
|
||||
#define HOMEBREW_DOMAIN "HOMEBREW"
|
||||
#define MUSIC_DOMAIN "MUSIC"
|
||||
#define FTP_DOMAIN "FTP"
|
||||
|
||||
#define DEVELOPERS "Fledge68"
|
||||
#define PAST_DEVELOPERS "FIX94, OverjoY, Hibernatus, Narolez, Hulk, Miigotu, r-win"
|
||||
|
@ -156,8 +156,8 @@ bool DeviceHandler::MountAllUSB()
|
||||
}
|
||||
if(!result)
|
||||
result = usb.Mount(0, DeviceName[USB1], true); /* Force FAT */
|
||||
if(result && usb_libogc_mode)
|
||||
CreateUSBKeepAliveThread();
|
||||
//if(result && usb_libogc_mode)
|
||||
// CreateUSBKeepAliveThread();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,7 @@ bool GameTDB::OpenFile(const char *filepath)
|
||||
void GameTDB::CloseFile()
|
||||
{
|
||||
OffsetMap.clear();
|
||||
vector<GameOffsets>().swap(OffsetMap);
|
||||
|
||||
if(GameNodeCache)
|
||||
MEM2_free(GameNodeCache);
|
||||
|
@ -673,6 +673,7 @@ void CCoverFlow::clear(void)
|
||||
MEM2_free(m_covers);
|
||||
m_covers = NULL;
|
||||
m_items.clear();
|
||||
//vector<CItem>().swap(m_items);
|
||||
}
|
||||
|
||||
void CCoverFlow::shutdown(void)
|
||||
@ -1176,7 +1177,7 @@ void CCoverFlow::_drawTitle(int i, bool mirror, bool rectangle)
|
||||
if (m_covers[i].txtColor == 0) return;
|
||||
|
||||
color.a = mirror ? (u8)((float)m_covers[i].txtColor * m_txtMirrorAlpha) : m_covers[i].txtColor;
|
||||
if (rectangle && !mirror)
|
||||
if (rectangle && !mirror)// rectangle (mainloop adjusting) is never set true
|
||||
{
|
||||
// GX setup
|
||||
GX_SetNumTevStages(1);
|
||||
@ -2464,7 +2465,7 @@ void CCoverFlow::_coverTick(int i)
|
||||
m_covers[i].txtAngle += (m_covers[i].txtTargetAngle - m_covers[i].txtAngle) * speed;
|
||||
m_covers[i].txtPos += (m_covers[i].txtTargetPos - m_covers[i].txtPos) * speed;
|
||||
int colorDist = (int)m_covers[i].txtTargetColor - (int)m_covers[i].txtColor;
|
||||
m_covers[i].txtColor += abs(colorDist) >= 8 ? (u8)(colorDist / 8) : (u8)colorDist;
|
||||
m_covers[i].txtColor += abs(colorDist) >= 2 ? (u8)(colorDist / 2) : (u8)colorDist;
|
||||
m_covers[i].title.tick();
|
||||
}
|
||||
|
||||
@ -2776,7 +2777,7 @@ const char *CCoverFlow::getPathId(const dir_discHdr *curHdr, bool extension)
|
||||
if(strrchr(curHdr->path, '/') != NULL)
|
||||
{
|
||||
if(curHdr->type == TYPE_HOMEBREW || extension)
|
||||
NameOrID = strrchr(curHdr->path, '/') + 1;//returns title.ext or folder name for boot.dol
|
||||
NameOrID = strrchr(curHdr->path, '/') + 1;//returns title.ext or folder name for app
|
||||
else
|
||||
NameOrID = fmt("%ls", curHdr->title);// title without extension in lowercase
|
||||
}
|
||||
@ -2840,14 +2841,9 @@ CCoverFlow::CLRet CCoverFlow::_loadCoverTex(u32 i, bool box, bool hq, bool blank
|
||||
u32 fileSize = stat_buf.st_size;
|
||||
|
||||
SWFCHeader header;
|
||||
if(fileSize > sizeof header)
|
||||
if(fileSize > sizeof(header))
|
||||
{
|
||||
size_t readLen;
|
||||
do {
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
readLen = fread(&header, 1, sizeof header, fp);
|
||||
} while (readLen != sizeof header);
|
||||
//fread(&header, 1, sizeof header, fp);
|
||||
fread(&header, 1, sizeof(header), fp);
|
||||
//make sure wfc cache file matches what we want
|
||||
if(header.newFmt == 1 && (header.full != 0) == box && (header.cmpr != 0) == m_compressTextures)
|
||||
{
|
||||
@ -2867,18 +2863,14 @@ CCoverFlow::CLRet CCoverFlow::_loadCoverTex(u32 i, bool box, bool hq, bool blank
|
||||
if(header.zipped != 0)//if it's compressed ie. zipped
|
||||
{
|
||||
u8 *ptrTex = (u8*)MEM2_alloc(bufSize);
|
||||
u8 *zBuffer = (u8*)MEM2_alloc(fileSize - sizeof header);
|
||||
u8 *zBuffer = (u8*)MEM2_alloc(fileSize - sizeof(header));
|
||||
if(ptrTex == NULL || zBuffer == NULL)
|
||||
allocFailed = true;
|
||||
else
|
||||
{
|
||||
size_t readLen;
|
||||
do {
|
||||
fseek(fp, sizeof header, SEEK_SET);
|
||||
readLen = fread(zBuffer, 1, fileSize - sizeof header, fp);
|
||||
} while (readLen != (fileSize - sizeof header));
|
||||
fread(zBuffer, 1, fileSize - sizeof(header), fp);
|
||||
uLongf size = bufSize;
|
||||
if(uncompress(ptrTex, &size, zBuffer, fileSize - sizeof header) == Z_OK && size == bufSize)
|
||||
if(uncompress(ptrTex, &size, zBuffer, fileSize - sizeof(header)) == Z_OK && size == bufSize)
|
||||
memcpy(tex.data, ptrTex + bufSize - texLen, texLen);
|
||||
}
|
||||
free(zBuffer);
|
||||
@ -2890,11 +2882,8 @@ CCoverFlow::CLRet CCoverFlow::_loadCoverTex(u32 i, bool box, bool hq, bool blank
|
||||
allocFailed = true;
|
||||
else
|
||||
{
|
||||
size_t readLen;
|
||||
do {
|
||||
fseek(fp, sizeof header + bufSize - texLen, SEEK_SET);
|
||||
readLen = fread(tex.data, 1, texLen, fp);
|
||||
} while (readLen != texLen);
|
||||
fseek(fp, sizeof(header) + bufSize - texLen, SEEK_SET);
|
||||
fread(tex.data, 1, texLen, fp);
|
||||
}
|
||||
}
|
||||
if(!allocFailed)
|
||||
|
@ -221,8 +221,8 @@ private:
|
||||
float txtTargetAngle;
|
||||
Vector3D txtPos;
|
||||
Vector3D txtTargetPos;
|
||||
u8 txtColor;
|
||||
u8 txtTargetColor;
|
||||
u8 txtColor;// actually is title alpha (color.a)
|
||||
u8 txtTargetColor;// title alpha (255 = full show, 0 = no show)
|
||||
CText title;
|
||||
CColor shadowColor;
|
||||
CColor targetShadowColor;
|
||||
|
@ -309,6 +309,16 @@ void CButtonsMgr::moveBy(s16 id, int x, int y, bool instant)
|
||||
}
|
||||
}
|
||||
|
||||
void CButtonsMgr::getTotalHeight(s16 id, int &height)
|
||||
{
|
||||
if (id == -1) return;
|
||||
if (id < (s32)m_elts.size())
|
||||
{
|
||||
SLabel *s = (SLabel*)m_elts[id];
|
||||
height = s->text.getTotalHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void CButtonsMgr::getDimensions(s16 id, int &x, int &y, u32 &width, u32 &height)
|
||||
{
|
||||
if (id == -1) return;
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
void setProgress(s16 id, float f, bool instant = false);
|
||||
void reset(s16 id, bool instant = false);
|
||||
void moveBy(s16 id, int x, int y, bool instant = false);
|
||||
void getTotalHeight(s16 id, int &height);
|
||||
void getDimensions(s16 id, int &x, int &y, u32 &width, u32 &height);
|
||||
void hide(s16 id, int dx, int dy, float scaleX, float scaleY, bool instant = false);
|
||||
void hide(s16 id, bool instant = false);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "fileOps/fileOps.h"
|
||||
#include "gui/coverflow.hpp"
|
||||
#include "gui/text.hpp"
|
||||
#include "loader/sys.h"
|
||||
|
||||
ListGenerator m_cacheList;
|
||||
Config CustomTitles;
|
||||
@ -39,6 +40,12 @@ void ListGenerator::Init(const char *settingsDir, const char *Language)
|
||||
if(Language != NULL) gameTDB_Language = Language;
|
||||
}
|
||||
|
||||
void ListGenerator::Clear(void)
|
||||
{
|
||||
m_cacheList.clear();
|
||||
vector<dir_discHdr>().swap(m_cacheList);
|
||||
}
|
||||
|
||||
void ListGenerator::OpenConfigs()
|
||||
{
|
||||
gameTDB.OpenFile(gameTDB_Path.c_str());
|
||||
@ -215,7 +222,10 @@ static void Create_Channel_List(bool realNAND)
|
||||
ListElement.index = m_cacheList.size();
|
||||
ListElement.settings[0] = TITLE_UPPER(chan->title);
|
||||
ListElement.settings[1] = TITLE_LOWER(chan->title);
|
||||
strncpy(ListElement.id, chan->id, 4);
|
||||
if(chan->title == HBC_108)
|
||||
strncpy(ListElement.id, "JODI", 4);
|
||||
else
|
||||
strncpy(ListElement.id, chan->id, 4);
|
||||
ListElement.casecolor = CustomTitles.getColor("COVERS", ListElement.id, 0xFFFFFF).intVal();
|
||||
const char *CustomTitle = CustomTitles.getString("TITLES", ListElement.id).c_str();
|
||||
if(gameTDB.IsLoaded())
|
||||
@ -242,6 +252,7 @@ static void Create_Channel_List(bool realNAND)
|
||||
void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
||||
const string& DBName, bool UpdateCache)
|
||||
{
|
||||
Clear();
|
||||
if(!DBName.empty())
|
||||
{
|
||||
if(UpdateCache)
|
||||
@ -254,8 +265,7 @@ void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const v
|
||||
fsop_deleteFile(DBName.c_str());
|
||||
}
|
||||
}
|
||||
//if(Flow != COVERFLOW_PLUGIN)
|
||||
OpenConfigs();
|
||||
OpenConfigs();
|
||||
if(Flow == COVERFLOW_WII)
|
||||
{
|
||||
if(DeviceHandle.GetFSType(Device) == PART_FS_WBFS)
|
||||
@ -342,6 +352,7 @@ void GetFiles(const char *Path, const vector<string>& FileTypes,
|
||||
void ListGenerator::createSFList(u8 maxBtns, Config &m_sourceMenuCfg, bool show_homebrew, bool show_channel, bool show_plugin, bool show_gc,
|
||||
const string& sourceDir, const string& DBName, bool UpdateCache)
|
||||
{
|
||||
Clear();
|
||||
if(!DBName.empty())
|
||||
{
|
||||
if(UpdateCache)
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
void createSFList(u8 maxBtns, Config &m_sourceMenuCfg, bool show_homebrew, bool show_channel, bool show_plugin, bool show_gc, const string& sourceDir,
|
||||
const string& DBName, bool UpdateCache);
|
||||
void Init(const char *settingsDir, const char *Language);
|
||||
void Clear();
|
||||
void CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
||||
const string& DBName, bool UpdateCache);
|
||||
u32 Color;
|
||||
|
@ -113,8 +113,8 @@ int main(int argc, char **argv)
|
||||
mainMenu.main();
|
||||
}
|
||||
//Exit WiiFlow, no game booted...
|
||||
mainMenu.cleanup();
|
||||
ShutdownBeforeExit();
|
||||
mainMenu.cleanup();// cleanup and clear memory
|
||||
ShutdownBeforeExit();// unmount devices and close inputs
|
||||
Sys_Exit();
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include "loader/playlog.h"
|
||||
#include "loader/wbfs.h"
|
||||
#include "music/SoundHandler.hpp"
|
||||
#include "network/FTP_Dir.hpp"
|
||||
#include "network/ftp.h"
|
||||
#include "network/gcard.h"
|
||||
#include "unzip/U8Archive.h"
|
||||
#include "sicksaxis-wrapper/sicksaxis-wrapper.h"
|
||||
@ -98,9 +96,6 @@ CMenu::CMenu()
|
||||
m_thrdDone = false;
|
||||
m_thrdWritten = 0;
|
||||
m_thrdTotal = 0;
|
||||
/* ftp stuff */
|
||||
m_ftp_inited = false;
|
||||
m_init_ftp = false;
|
||||
/* screensaver */
|
||||
no_input_time = 0;
|
||||
/* Autoboot stuff */
|
||||
@ -148,7 +143,7 @@ void CMenu::init()
|
||||
gprintf("Wiiflow boot.dol Location: %s\n", m_appDir.c_str());
|
||||
fsop_MakeFolder(m_appDir.c_str());
|
||||
|
||||
/* Load/Create wiiflow.ini so we can get settings to start Gecko, FTP, and Network */
|
||||
/* Load/Create wiiflow.ini so we can get settings to start Gecko and Network */
|
||||
m_cfg.load(fmt("%s/" CFG_FILENAME, m_appDir.c_str()));
|
||||
/* Check if we want WiFi Gecko */
|
||||
m_use_wifi_gecko = m_cfg.getBool("DEBUG", "wifi_gecko", false);
|
||||
@ -156,13 +151,8 @@ void CMenu::init()
|
||||
/* Check if we want SD Gecko */
|
||||
m_use_sd_logging = m_cfg.getBool("DEBUG", "sd_write_log", false);
|
||||
LogToSD_SetBuffer(m_use_sd_logging);
|
||||
/* Check if we want FTP */
|
||||
m_init_ftp = m_cfg.getBool(FTP_DOMAIN, "auto_start", false);
|
||||
ftp_allow_active = m_cfg.getBool(FTP_DOMAIN, "allow_active_mode", false);
|
||||
ftp_server_port = min(65535u, m_cfg.getUInt(FTP_DOMAIN, "server_port", 21));
|
||||
set_ftp_password(m_cfg.getString(FTP_DOMAIN, "password", "").c_str());
|
||||
/* Init Network if wanted */
|
||||
init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko || m_init_ftp);
|
||||
init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko);
|
||||
_netInit();
|
||||
|
||||
/* Try to find/make the wiiflow data directory */
|
||||
@ -221,7 +211,6 @@ void CMenu::init()
|
||||
/* GameCube stuff */
|
||||
m_devo_installed = DEVO_Installed(m_dataDir.c_str());
|
||||
m_nintendont_installed = Nintendont_Installed();
|
||||
m_show_gc = !m_cfg.getBool(GC_DOMAIN, "disable", ((m_devo_installed || m_nintendont_installed) == false));
|
||||
memset(gc_games_dir, 0, 64);
|
||||
strncpy(gc_games_dir, m_cfg.getString(GC_DOMAIN, "gc_games_dir", DF_GC_GAMES_DIR).c_str(), 64);
|
||||
if(strncmp(gc_games_dir, "%s:/", 4) != 0)
|
||||
@ -330,6 +319,7 @@ void CMenu::init()
|
||||
|
||||
/* Load categories and theme INI files */
|
||||
m_cat.load(fmt("%s/" CAT_FILENAME, m_settingsDir.c_str()));
|
||||
m_gcfg1.load(fmt("%s/" GAME_SETTINGS1_FILENAME, m_settingsDir.c_str()));
|
||||
string themeName = m_cfg.getString("GENERAL", "theme", "default");
|
||||
m_themeDataDir = fmt("%s/%s", m_themeDir.c_str(), themeName.c_str());
|
||||
m_theme.load(fmt("%s.ini", m_themeDataDir.c_str()));
|
||||
@ -421,7 +411,7 @@ void CMenu::init()
|
||||
|
||||
/* Init background Music Player and song info */
|
||||
MusicPlayer.Init(m_cfg, m_musicDir, fmt("%s/music", m_themeDataDir.c_str()));
|
||||
m_music_info = m_cfg.getBool("GENERAL", "display_music_info", true);
|
||||
m_music_info = m_cfg.getBool("GENERAL", "display_music_info", false);
|
||||
|
||||
/* Init Button Manager and build the menus */
|
||||
m_btnMgr.init();
|
||||
@ -611,8 +601,6 @@ void CMenu::_netInit(void)
|
||||
_initAsyncNetwork();
|
||||
while(net_get_status() == -EBUSY)
|
||||
usleep(100);
|
||||
if(m_init_ftp)
|
||||
m_ftp_inited = ftp_startThread();
|
||||
}
|
||||
|
||||
void CMenu::_setAA(int aa)
|
||||
@ -1264,7 +1252,6 @@ void CMenu::_buildMenus(void)
|
||||
_initMainMenu();
|
||||
_initErrorMenu();
|
||||
_initWad();
|
||||
_initFTP();
|
||||
_initWBFSMenu();
|
||||
_initConfigAdvMenu();
|
||||
_initConfigSndMenu();
|
||||
@ -1350,6 +1337,13 @@ SFont CMenu::_font(const char *domain, const char *key, u32 fontSize, u32 lineSp
|
||||
theme.fontSet.push_back(retFont);
|
||||
return retFont;
|
||||
}
|
||||
/* try default font in imgs folder
|
||||
if(retFont.fromFile(fmt("%s/font.ttf", m_imgsDir.c_str()), fonts[0].res, fonts[1].res, fonts[2].res, index, filename.c_str()))
|
||||
{
|
||||
// Default font
|
||||
theme.fontSet.push_back(retFont);
|
||||
return retFont;
|
||||
}*/
|
||||
/* Fallback to default font */
|
||||
if(retFont.fromBuffer(m_base_font, m_base_font_size, fonts[0].res, fonts[1].res, fonts[2].res, index, filename.c_str()))
|
||||
{
|
||||
@ -1703,7 +1697,7 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
|
||||
// check if we need to start screensaver
|
||||
if(!m_vid.showingWaitMessage())
|
||||
{
|
||||
if(!m_cfg.getBool("GENERAL", "screensaver_disabled", false))
|
||||
if(!m_cfg.getBool("GENERAL", "screensaver_disabled", true))
|
||||
m_vid.screensaver(NoInputTime(), m_cfg.getInt("GENERAL", "screensaver_idle_seconds", 60));
|
||||
m_vid.render();
|
||||
}
|
||||
@ -1928,7 +1922,6 @@ void CMenu::_updateText(void)
|
||||
_textCoverBanner();
|
||||
_textExplorer();
|
||||
_textWad();
|
||||
_textFTP();
|
||||
}
|
||||
|
||||
const wstringEx CMenu::_fmt(const char *key, const wchar_t *def)
|
||||
@ -1941,64 +1934,64 @@ const wstringEx CMenu::_fmt(const char *key, const wchar_t *def)
|
||||
void CMenu::_initCF(void)
|
||||
{
|
||||
Config dump;
|
||||
const char *domain = _domainFromView();
|
||||
bool dumpGameLst = m_cfg.getBool("GENERAL", "dump_list", true);
|
||||
if(dumpGameLst) dump.load(fmt("%s/" TITLES_DUMP_FILENAME, m_settingsDir.c_str()));
|
||||
|
||||
CoverFlow.clear();
|
||||
CoverFlow.reserve(m_gameList.size());
|
||||
|
||||
bool dumpGameLst = m_cfg.getBool(domain, "dump_list", true);
|
||||
if(dumpGameLst) dump.load(fmt("%s/" TITLES_DUMP_FILENAME, m_settingsDir.c_str()));
|
||||
|
||||
m_gcfg1.load(fmt("%s/" GAME_SETTINGS1_FILENAME, m_settingsDir.c_str()));
|
||||
|
||||
const vector<bool> &EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
|
||||
for(vector<dir_discHdr>::iterator element = m_gameList.begin(); element != m_gameList.end(); ++element)
|
||||
for(vector<dir_discHdr>::iterator hdr = m_gameList.begin(); hdr != m_gameList.end(); ++hdr)
|
||||
{
|
||||
char tmp[MAX_FAT_PATH];
|
||||
memset(tmp, 0, MAX_FAT_PATH);
|
||||
const char *id = NULL;
|
||||
u64 chantitle = TITLE_ID(element->settings[0],element->settings[1]);
|
||||
const char *catID = NULL;
|
||||
const char *favDomain = "FAVORITES";
|
||||
const char *adultDomain = "ADULTONLY";
|
||||
|
||||
char tmp1[74];//title plus magic#
|
||||
memset(tmp1, 0, 74);
|
||||
char tmp2[64];
|
||||
memset(tmp2, 0, 64);
|
||||
|
||||
if(m_sourceflow)
|
||||
{
|
||||
char srctmp[63] = "source/";
|
||||
memcpy(tmp, srctmp, 63);
|
||||
wcstombs(srctmp, element->title, 63);
|
||||
strcat(tmp, srctmp);
|
||||
id = tmp;
|
||||
CoverFlow.addItem(&(*hdr), 0, 0);
|
||||
continue;
|
||||
/*strcpy(tmp1, "source/");
|
||||
wcstombs(tmp2, hdr->title, 64);
|
||||
strcat(tmp1, tmp2);
|
||||
id = tmp1;*/
|
||||
}
|
||||
else if(element->type == TYPE_HOMEBREW)
|
||||
id = strrchr(element->path, '/') + 1;
|
||||
else if(element->type == TYPE_PLUGIN)
|
||||
else if(hdr->type == TYPE_HOMEBREW)
|
||||
{
|
||||
if(strstr(element->path, ":/") != NULL)
|
||||
{
|
||||
if(*(strchr(element->path, '/') + 1) != '\0')
|
||||
strcat(tmp, strchr(element->path, '/') + 1);
|
||||
else
|
||||
strcat(tmp, element->path);
|
||||
if(strchr(tmp, '/') != NULL)
|
||||
*(strchr(tmp, '/') + 1) = '\0';
|
||||
}
|
||||
strcat(tmp, fmt("%ls",element->title));
|
||||
id = tmp;
|
||||
CoverFlow.addItem(&(*hdr), 0, 0);
|
||||
continue;
|
||||
//id = strrchr(hdr->path, '/') + 1;
|
||||
}
|
||||
else if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", hdr->settings[0]), 8);
|
||||
wcstombs(tmp2, hdr->title, 64);
|
||||
strcat(tmp1, m_plugin.PluginMagicWord);
|
||||
strcat(tmp1, fmt("/%s", tmp2));
|
||||
id = tmp1;
|
||||
catID = tmp2;
|
||||
favDomain = "FAVORITES_PLUGINS";
|
||||
adultDomain = "ADULTONLY_PLUGINS";
|
||||
}
|
||||
else
|
||||
{
|
||||
if((element->type == TYPE_CHANNEL || element->type == TYPE_EMUCHANNEL) && chantitle == HBC_108)
|
||||
strncpy(element->id, "JODI", 6);
|
||||
id = element->id;
|
||||
if(element->type == TYPE_GC_GAME && element->settings[0] == 1) /* disc 2 */
|
||||
id = hdr->id;
|
||||
if(hdr->type == TYPE_GC_GAME && hdr->settings[0] == 1) /* disc 2 */
|
||||
{
|
||||
strcat(tmp, fmt("%.6s_2", element->id));
|
||||
id = tmp;
|
||||
strcat(tmp1, fmt("%.6s_2", hdr->id));
|
||||
id = tmp1;
|
||||
}
|
||||
}
|
||||
if((!m_favorites || m_gcfg1.getBool("FAVORITES", id, false))
|
||||
&& (!m_locked || !m_gcfg1.getBool("ADULTONLY", id, false)))
|
||||
if((!m_favorites || m_gcfg1.getBool(favDomain, id, false))
|
||||
&& (!m_locked || !m_gcfg1.getBool(adultDomain, id, false)))
|
||||
{
|
||||
string catDomain;
|
||||
switch(element->type)
|
||||
const char *catDomain = NULL;
|
||||
switch(hdr->type)
|
||||
{
|
||||
case TYPE_CHANNEL:
|
||||
catDomain = "NAND";
|
||||
@ -2006,10 +1999,6 @@ void CMenu::_initCF(void)
|
||||
case TYPE_EMUCHANNEL:
|
||||
catDomain = "CHANNELS";
|
||||
break;
|
||||
case TYPE_HOMEBREW:
|
||||
case TYPE_SOURCE:
|
||||
catDomain = "HOMEBREW";
|
||||
break;
|
||||
case TYPE_GC_GAME:
|
||||
catDomain = "GAMECUBE";
|
||||
break;
|
||||
@ -2017,8 +2006,9 @@ void CMenu::_initCF(void)
|
||||
catDomain = "WII";
|
||||
break;
|
||||
default:
|
||||
catDomain = (m_plugin.GetPluginName(m_plugin.GetPluginPosition(element->settings[0]))).toUTF8();
|
||||
}
|
||||
catDomain = m_plugin.PluginMagicWord;
|
||||
break;
|
||||
}
|
||||
const char *requiredCats = m_cat.getString("GENERAL", "required_categories").c_str();
|
||||
const char *selectedCats = m_cat.getString("GENERAL", "selected_categories").c_str();
|
||||
const char *hiddenCats = m_cat.getString("GENERAL", "hidden_categories").c_str();
|
||||
@ -2027,7 +2017,7 @@ void CMenu::_initCF(void)
|
||||
u8 numHidCats = strlen(hiddenCats);
|
||||
if(numReqCats != 0 || numSelCats != 0 || numHidCats != 0) // if all 0 skip checking cats and show all games
|
||||
{
|
||||
const char *idCats = m_cat.getString(catDomain, id).c_str();
|
||||
const char *idCats = m_cat.getString(catDomain, hdr->type == TYPE_PLUGIN? catID : id).c_str();
|
||||
u8 numIdCats = strlen(idCats);
|
||||
bool inaCat = false;
|
||||
bool inHiddenCat = false;
|
||||
@ -2090,44 +2080,56 @@ void CMenu::_initCF(void)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int playcount = m_gcfg1.getInt("PLAYCOUNT", id, 0);
|
||||
unsigned int lastPlayed = m_gcfg1.getUInt("LASTPLAYED", id, 0);
|
||||
|
||||
if(dumpGameLst)
|
||||
dump.setWString(domain, id, element->title);
|
||||
|
||||
if(element->type == TYPE_PLUGIN && EnabledPlugins.size() > 0)
|
||||
if(dumpGameLst && hdr->type != TYPE_PLUGIN)
|
||||
{
|
||||
for(u8 j = 0; j < EnabledPlugins.size(); j++)
|
||||
const char *domain = NULL;
|
||||
switch(hdr->type)
|
||||
{
|
||||
if(EnabledPlugins.at(j) == true && element->settings[0] == m_plugin.getPluginMagic(j))
|
||||
{
|
||||
CoverFlow.addItem(&(*element), playcount, lastPlayed);
|
||||
case TYPE_CHANNEL:
|
||||
domain = "NAND";
|
||||
break;
|
||||
case TYPE_EMUCHANNEL:
|
||||
domain = "CHANNELS";
|
||||
break;
|
||||
case TYPE_GC_GAME:
|
||||
domain = "GAMECUBE";
|
||||
break;
|
||||
default:
|
||||
domain = "WII";
|
||||
break;
|
||||
}
|
||||
}
|
||||
dump.setWString(domain, id, hdr->title);
|
||||
}
|
||||
|
||||
if(hdr->type == TYPE_PLUGIN && m_plugin.GetEnableStatus(m_cfg, hdr->settings[0]))
|
||||
CoverFlow.addItem(&(*hdr), 0, 0);
|
||||
else
|
||||
CoverFlow.addItem(&(*element), playcount, lastPlayed);
|
||||
{
|
||||
int playcount = m_gcfg1.getInt("PLAYCOUNT", id, 0);
|
||||
unsigned int lastPlayed = m_gcfg1.getUInt("LASTPLAYED", id, 0);
|
||||
CoverFlow.addItem(&(*hdr), playcount, lastPlayed);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_gcfg1.unload();
|
||||
|
||||
if(dumpGameLst)
|
||||
{
|
||||
dump.save(true);
|
||||
m_cfg.setBool(domain, "dump_list", false);
|
||||
m_cfg.setBool("GENERAL", "dump_list", false);
|
||||
}
|
||||
|
||||
CoverFlow.setSorting(m_combined_view ? (Sorting)0 : (Sorting)m_cfg.getInt(_domainFromView(), "sort", 0));
|
||||
CoverFlow.setBoxMode(m_cfg.getBool("GENERAL", "box_mode", true));
|
||||
CoverFlow.setCompression(m_cfg.getBool("GENERAL", "allow_texture_compression", true));
|
||||
CoverFlow.setBufferSize(m_cfg.getInt("GENERAL", "cover_buffer", 20));
|
||||
CoverFlow.setSorting((Sorting)m_cfg.getInt(domain, "sort", 0));
|
||||
CoverFlow.setHQcover(m_cfg.getBool("GENERAL", "cover_use_hq", false));
|
||||
CoverFlow.start(m_imgsDir);
|
||||
|
||||
if(!CoverFlow.empty())
|
||||
{
|
||||
bool path = m_sourceflow || m_current_view == COVERFLOW_PLUGIN || m_current_view == COVERFLOW_HOMEBREW;
|
||||
if(m_current_view == COVERFLOW_MAX || !CoverFlow.findId(m_cfg.getString(domain, "current_item").c_str(), true, path))
|
||||
if(m_current_view == COVERFLOW_MAX || !CoverFlow.findId(m_cfg.getString(_domainFromView(), "current_item").c_str(), true, path))
|
||||
CoverFlow.defaultLoad();
|
||||
CoverFlow.startCoverLoader();
|
||||
}
|
||||
@ -2135,9 +2137,9 @@ void CMenu::_initCF(void)
|
||||
|
||||
bool CMenu::_loadList(void)
|
||||
{
|
||||
CoverFlow.clear();
|
||||
m_cacheList.clear();
|
||||
CoverFlow.clear();// clears filtered list (m_items), cover list (m_covers), and cover textures and stops coverloader
|
||||
m_gameList.clear();
|
||||
vector<dir_discHdr>().swap(m_gameList);
|
||||
NANDemuView = false;
|
||||
|
||||
if(m_sourceflow)
|
||||
@ -2145,11 +2147,12 @@ bool CMenu::_loadList(void)
|
||||
string cacheDir(fmt("%s/sourceflow.db", m_listCacheDir.c_str()));
|
||||
bool updateCache = m_cfg.getBool("SOURCEFLOW", "update_cache");
|
||||
u8 maxBtns = m_cfg.getInt("GENERAL", "max_source_buttons", 71);
|
||||
bool show_homebrew = (!m_locked || !m_cfg.getBool(HOMEBREW_DOMAIN, "parental", false));
|
||||
m_cacheList.createSFList(maxBtns, m_source, show_homebrew, show_channel, show_plugin, show_gamecube, m_sourceDir, cacheDir, updateCache);
|
||||
m_cfg.remove("SOURCEFLOW", "update_cache");
|
||||
for(vector<dir_discHdr>::iterator tmp_itr = m_cacheList.begin(); tmp_itr != m_cacheList.end(); tmp_itr++)
|
||||
m_gameList.push_back(*tmp_itr);
|
||||
m_cacheList.clear();
|
||||
m_cacheList.Clear();
|
||||
return true;
|
||||
}
|
||||
if(m_current_view == COVERFLOW_HOMEBREW)
|
||||
@ -2171,7 +2174,7 @@ bool CMenu::_loadList(void)
|
||||
if(m_current_view == COVERFLOW_GAMECUBE || (m_combined_view && m_cfg.getBool(GC_DOMAIN, "source")))
|
||||
_loadGamecubeList();
|
||||
|
||||
m_cacheList.clear();
|
||||
m_cacheList.Clear();
|
||||
|
||||
gprintf("Games found: %i\n", m_gameList.size());
|
||||
return m_gameList.size() > 0 ? true : false;
|
||||
@ -2183,7 +2186,6 @@ bool CMenu::_loadWiiList(void)
|
||||
if(!DeviceHandle.IsInserted(currentPartition))
|
||||
return false;
|
||||
|
||||
m_cacheList.clear();
|
||||
DeviceHandle.OpenWBFS(currentPartition);
|
||||
string gameDir(fmt(wii_games_dir, DeviceName[currentPartition]));
|
||||
string cacheDir(fmt("%s/%s_wii.db", m_listCacheDir.c_str(), DeviceName[currentPartition]));
|
||||
@ -2202,14 +2204,11 @@ bool CMenu::_loadHomebrewList()
|
||||
if(!DeviceHandle.IsInserted(currentPartition))
|
||||
return false;
|
||||
|
||||
m_cacheList.clear();
|
||||
string gameDir(fmt(HOMEBREW_DIR, DeviceName[currentPartition]));
|
||||
string cacheDir(fmt("%s/%s_homebrew.db", m_listCacheDir.c_str(), DeviceName[currentPartition]));
|
||||
bool updateCache = m_cfg.getBool(HOMEBREW_DOMAIN, "update_cache");
|
||||
m_cacheList.CreateList(COVERFLOW_HOMEBREW, currentPartition, gameDir, stringToVector(".dol|.elf", '|'), cacheDir, updateCache);
|
||||
m_cfg.remove(HOMEBREW_DOMAIN, "update_cache");
|
||||
m_cacheList.CreateList(COVERFLOW_HOMEBREW, currentPartition, gameDir, stringToVector(".dol|.elf", '|'), std::string(), false);
|
||||
for(vector<dir_discHdr>::iterator tmp_itr = m_cacheList.begin(); tmp_itr != m_cacheList.end(); tmp_itr++)
|
||||
m_gameList.push_back(*tmp_itr);
|
||||
m_cacheList.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2219,7 +2218,6 @@ bool CMenu::_loadGamecubeList()
|
||||
if(!DeviceHandle.IsInserted(currentPartition))
|
||||
return false;
|
||||
|
||||
m_cacheList.clear();
|
||||
string gameDir(fmt(gc_games_dir, DeviceName[currentPartition]));
|
||||
string cacheDir(fmt("%s/%s_gamecube.db", m_listCacheDir.c_str(), DeviceName[currentPartition]));
|
||||
bool updateCache = m_cfg.getBool(GC_DOMAIN, "update_cache");
|
||||
@ -2236,7 +2234,6 @@ bool CMenu::_loadChannelList(void)
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "real_nand"))
|
||||
{
|
||||
NANDemuView = false;
|
||||
m_cacheList.clear();
|
||||
m_cacheList.CreateList(COVERFLOW_CHANNEL, 9, std::string(), NullVector, std::string(), false);
|
||||
for(vector<dir_discHdr>::iterator tmp_itr = m_cacheList.begin(); tmp_itr != m_cacheList.end(); tmp_itr++)
|
||||
m_gameList.push_back(*tmp_itr);
|
||||
@ -2244,11 +2241,8 @@ bool CMenu::_loadChannelList(void)
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand"))
|
||||
{
|
||||
NANDemuView = true;
|
||||
m_cacheList.clear();
|
||||
string emuPath;
|
||||
int emuPartition = _FindEmuPart(emuPath, false, false);//check if exist & has sysconf, settings.txt, & RFL_DB.dat
|
||||
//if(emuPartition < 0)// && m_nand_view != "both")
|
||||
// return false;// emu nand not found - menu_main will ask user to extract nand, disable emunand, or change partition
|
||||
if(emuPartition >= 0)
|
||||
{
|
||||
/* copy real NAND sysconf, settings.txt, & RFL_DB.dat if you want to, they are replaced if they already exist */
|
||||
@ -2264,53 +2258,52 @@ bool CMenu::_loadChannelList(void)
|
||||
m_gameList.push_back(*tmp_itr);
|
||||
}
|
||||
}
|
||||
m_cacheList.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMenu::_loadPluginList()
|
||||
{
|
||||
currentPartition = m_cfg.getInt(PLUGIN_DOMAIN, "partition", SD);
|
||||
if(!DeviceHandle.IsInserted(currentPartition))
|
||||
return false;
|
||||
|
||||
bool addGamecube = false;
|
||||
bool addWii = false;
|
||||
bool addChannel = false;
|
||||
bool addEmuChannel = false;
|
||||
bool updateCache = m_cfg.getBool(PLUGIN_DOMAIN, "update_cache");
|
||||
|
||||
for(u8 i = 0; i < m_numPlugins; ++i)
|
||||
for(u8 i = 0; m_plugin.PluginExist(i); ++i)
|
||||
{
|
||||
m_cacheList.clear();
|
||||
u32 Magic = m_plugin.getPluginMagic(i);
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", Magic), 8);
|
||||
if(!m_cfg.getBool(PLUGIN_ENABLED, m_plugin.PluginMagicWord, true))
|
||||
if(!m_plugin.GetEnableStatus(m_cfg, Magic))
|
||||
continue;
|
||||
string romDir = m_plugin.GetRomDir(i);
|
||||
if(romDir.find("scummvm.ini") == string::npos)
|
||||
int romsPartition = m_plugin.GetRomPartition(i);
|
||||
if(romsPartition < 0)
|
||||
romsPartition = m_cfg.getInt(PLUGIN_DOMAIN, "partition", 0);
|
||||
currentPartition = romsPartition;
|
||||
if(!DeviceHandle.IsInserted(currentPartition))
|
||||
continue;
|
||||
const char *romDir = m_plugin.GetRomDir(i);
|
||||
if(strcasecmp(romDir, "scummvm.ini") != 0)
|
||||
{
|
||||
if(string(m_plugin.PluginMagicWord) == "4e47434d")
|
||||
if(strncasecmp(m_plugin.PluginMagicWord, "4E47434D", 8) == 0)
|
||||
{
|
||||
addGamecube = true;
|
||||
continue;
|
||||
}
|
||||
if(string(m_plugin.PluginMagicWord) == "4e574949")
|
||||
if(strncasecmp(m_plugin.PluginMagicWord, "4E574949", 8) == 0)
|
||||
{
|
||||
addWii = true;
|
||||
continue;
|
||||
}
|
||||
if(string(m_plugin.PluginMagicWord) == "4e414e44")
|
||||
if(strncasecmp(m_plugin.PluginMagicWord, "4E414E44", 8) == 0)
|
||||
{
|
||||
addChannel = true;
|
||||
continue;
|
||||
}
|
||||
if(string(m_plugin.PluginMagicWord) == "454e414e")
|
||||
if(strncasecmp(m_plugin.PluginMagicWord, "454E414E", 8) == 0)
|
||||
{
|
||||
addEmuChannel = true;
|
||||
continue;
|
||||
}
|
||||
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin.GetRomDir(i)));
|
||||
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], romDir));
|
||||
string cacheDir(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin.PluginMagicWord));
|
||||
vector<string> FileTypes = stringToVector(m_plugin.GetFileTypes(i), '|');
|
||||
m_cacheList.Color = m_plugin.GetCaseColor(i);
|
||||
@ -2327,9 +2320,10 @@ bool CMenu::_loadPluginList()
|
||||
scummvmList = m_plugin.ParseScummvmINI(scummvm, DeviceName[currentPartition], Magic);
|
||||
for(vector<dir_discHdr>::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++)
|
||||
m_gameList.push_back(*tmp_itr);
|
||||
scummvmList.clear();
|
||||
vector<dir_discHdr>().swap(scummvmList);
|
||||
}
|
||||
}
|
||||
m_cacheList.clear();
|
||||
if(addGamecube)
|
||||
_loadGamecubeList();
|
||||
|
||||
@ -2342,7 +2336,6 @@ bool CMenu::_loadPluginList()
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", addEmuChannel ? true : false);
|
||||
_loadChannelList();
|
||||
}
|
||||
m_cacheList.clear();
|
||||
m_cfg.remove(PLUGIN_DOMAIN, "update_cache");
|
||||
return true;
|
||||
}
|
||||
|
@ -56,8 +56,6 @@ public:
|
||||
u8 enabledPluginsCount;
|
||||
u8 m_catStartPage;
|
||||
bool m_clearCats;
|
||||
bool show_homebrew;
|
||||
bool parental_homebrew;
|
||||
bool show_channel;
|
||||
bool show_plugin;
|
||||
bool show_gamecube;
|
||||
@ -204,10 +202,8 @@ private:
|
||||
s16 m_mainBtnSelPart;
|
||||
s16 m_mainLblMessage;
|
||||
s16 m_mainLblUser[6];
|
||||
bool m_show_gc;
|
||||
bool m_devo_installed;
|
||||
bool m_nintendont_installed;
|
||||
bool m_GameTDBAvailable;
|
||||
//Main Config menus
|
||||
s16 m_configLblPage;
|
||||
s16 m_configBtnPageM;
|
||||
@ -895,7 +891,6 @@ private:
|
||||
void _initExplorer();
|
||||
void _initWad();
|
||||
void _initPathsMenu();
|
||||
void _initFTP();
|
||||
//
|
||||
void _textSource(void);
|
||||
void _textCfgSrc(void);
|
||||
@ -927,7 +922,6 @@ private:
|
||||
void _textExplorer(void);
|
||||
void _textWad(void);
|
||||
void _textPaths(void);
|
||||
void _textFTP(void);
|
||||
//
|
||||
void _refreshBoot();
|
||||
void _refreshCfgSrc();
|
||||
@ -967,7 +961,6 @@ private:
|
||||
void _hideExplorer(bool instant = false);
|
||||
void _hideWad(bool instant = false);
|
||||
void _hidePaths(bool instant = false);
|
||||
void _hideFTP(bool instant = false);
|
||||
//
|
||||
void _showError(void);
|
||||
void _showMain(void);
|
||||
@ -1002,7 +995,6 @@ private:
|
||||
void _showExplorer(void);
|
||||
void _showWad(void);
|
||||
void _showPaths(void);
|
||||
void _showFTP(void);
|
||||
|
||||
void _setSrcOptions(void);
|
||||
bool _sideCover(const char *magic);
|
||||
@ -1012,7 +1004,6 @@ private:
|
||||
void _updatePluginText(void);
|
||||
void _updatePluginCheckboxes(void);
|
||||
void _updateCheckboxes(void);
|
||||
void _updateFTP(void);
|
||||
void _getIDCats(void);
|
||||
void _setIDCats(void);
|
||||
void _setBg(const TexData &bgTex, const TexData &bglqTex);
|
||||
@ -1030,7 +1021,6 @@ private:
|
||||
int _configAdv(void);
|
||||
int _configSnd(void);
|
||||
int _NandEmuCfg(void);
|
||||
int _AutoCreateNand(void);
|
||||
int _AutoExtractSave(string gameId);
|
||||
int _FlashSave(string gameId);
|
||||
enum configPageChanges
|
||||
@ -1062,8 +1052,6 @@ private:
|
||||
void _PluginSettings();
|
||||
void _CategorySettings(bool fromGameSet = false);
|
||||
bool _Home();
|
||||
void _FTP();
|
||||
bool _FTP_Loop();
|
||||
bool _ExitTo();
|
||||
bool _Boot();
|
||||
void _Paths();
|
||||
@ -1077,8 +1065,6 @@ private:
|
||||
bool m_use_wifi_gecko;
|
||||
bool m_use_sd_logging;
|
||||
bool init_network;
|
||||
bool m_init_ftp;
|
||||
bool m_ftp_inited;
|
||||
void _netInit();
|
||||
bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file);
|
||||
int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false);
|
||||
|
@ -5,24 +5,22 @@
|
||||
#include "loader/cios.h"
|
||||
#include "const_str.hpp"
|
||||
|
||||
const int pixels_to_skip = 10;
|
||||
|
||||
extern const u8 english_txt[];
|
||||
static const wstringEx ENGLISH_TXT_W((const char*)english_txt);
|
||||
|
||||
//About menu
|
||||
s16 m_aboutLblTitle;
|
||||
s16 m_aboutLblInfo;
|
||||
s16 m_aboutLblUser[4];
|
||||
s16 m_aboutLblIOS;
|
||||
|
||||
bool showHelp;
|
||||
|
||||
void CMenu::_about(bool help)
|
||||
{
|
||||
showHelp = help;
|
||||
int pixels_to_skip = 10;
|
||||
int amount_of_skips = 0;
|
||||
int thanks_x = 0, thanks_y = 0;
|
||||
u32 thanks_w = 0, thanks_h = 0;
|
||||
int xtra_skips = 0;
|
||||
bool first = true;
|
||||
|
||||
_textAbout();
|
||||
@ -30,30 +28,42 @@ void CMenu::_about(bool help)
|
||||
|
||||
SetupInput();
|
||||
_showAbout();
|
||||
|
||||
int thanks_h = m_theme.getInt("ABOUT/INFO", "height", 300);
|
||||
int thanks_th = 0;
|
||||
|
||||
while(!m_exit)
|
||||
{
|
||||
_mainLoopCommon();
|
||||
if(amount_of_skips == 0) // Check dimensions in the loop, because the animation can have an effect
|
||||
m_btnMgr.getDimensions(m_aboutLblInfo, thanks_x, thanks_y, thanks_w, thanks_h); // Get original dimensions
|
||||
if(first)
|
||||
{
|
||||
m_btnMgr.getTotalHeight(m_aboutLblInfo, thanks_th);
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, -1);
|
||||
amount_of_skips++;
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, -pixels_to_skip);
|
||||
first = false;
|
||||
}
|
||||
|
||||
if ((BTN_DOWN_PRESSED || BTN_DOWN_HELD) && !(m_thrdWorking && m_thrdStop))
|
||||
if ((BTN_DOWN_PRESSED || BTN_DOWN_HELD) && !(m_thrdWorking && m_thrdStop) && thanks_th >thanks_h)
|
||||
{
|
||||
if (thanks_h - (amount_of_skips * pixels_to_skip) > (m_vid.height2D() - (35 + thanks_y)))
|
||||
if((thanks_th - amount_of_skips * pixels_to_skip) >= thanks_h)
|
||||
{
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, -pixels_to_skip);
|
||||
amount_of_skips++;
|
||||
}
|
||||
else if((thanks_th - amount_of_skips * pixels_to_skip) < thanks_h && xtra_skips == 0)
|
||||
{
|
||||
xtra_skips = pixels_to_skip - ((thanks_th - amount_of_skips * pixels_to_skip) - thanks_h);
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, -xtra_skips);
|
||||
}
|
||||
}
|
||||
else if ((BTN_UP_PRESSED || BTN_UP_HELD) && !(m_thrdWorking && m_thrdStop))
|
||||
{
|
||||
if (amount_of_skips > 1)
|
||||
if(xtra_skips > 0)
|
||||
{
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, xtra_skips);
|
||||
xtra_skips = 0;
|
||||
}
|
||||
else if (amount_of_skips > 0)
|
||||
{
|
||||
m_btnMgr.moveBy(m_aboutLblInfo, 0, pixels_to_skip);
|
||||
amount_of_skips--;
|
||||
|
@ -20,9 +20,9 @@
|
||||
|
||||
s16 m_bootLblTitle;
|
||||
s16 m_bootBtnBack;
|
||||
s16 m_bootLblPage;
|
||||
/*s16 m_bootLblPage;
|
||||
s16 m_bootBtnPageM;
|
||||
s16 m_bootBtnPageP;
|
||||
s16 m_bootBtnPageP;*/
|
||||
s16 m_bootLblUser[4];
|
||||
|
||||
s16 m_bootLblLoadCIOS;
|
||||
@ -39,20 +39,17 @@ s16 m_bootBtnUSBPort;
|
||||
s16 m_bootLblAsyncNet;
|
||||
s16 m_bootBtnAsyncNet;
|
||||
|
||||
s16 m_bootLblFtpOnBoot;
|
||||
s16 m_bootBtnFtpOnBoot;
|
||||
|
||||
u8 set_port = 0;
|
||||
u8 boot_curPage = 1;
|
||||
u8 boot_Pages = 2;
|
||||
//u8 boot_Pages = 2;
|
||||
|
||||
static void showBoot(void)
|
||||
{
|
||||
m_btnMgr.show(m_bootLblTitle);
|
||||
m_btnMgr.show(m_bootBtnBack);
|
||||
m_btnMgr.show(m_bootLblPage);
|
||||
/*m_btnMgr.show(m_bootLblPage);
|
||||
m_btnMgr.show(m_bootBtnPageM);
|
||||
m_btnMgr.show(m_bootBtnPageP);
|
||||
m_btnMgr.show(m_bootBtnPageP);*/
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_bootLblUser); ++i)
|
||||
if(m_bootLblUser[i] != -1)
|
||||
m_btnMgr.show(m_bootLblUser[i]);
|
||||
@ -64,9 +61,9 @@ static void hideBoot(bool instant, bool common)
|
||||
{
|
||||
m_btnMgr.hide(m_bootLblTitle, instant);
|
||||
m_btnMgr.hide(m_bootBtnBack, instant);
|
||||
m_btnMgr.hide(m_bootLblPage, instant);
|
||||
/*m_btnMgr.hide(m_bootLblPage, instant);
|
||||
m_btnMgr.hide(m_bootBtnPageM, instant);
|
||||
m_btnMgr.hide(m_bootBtnPageP, instant);
|
||||
m_btnMgr.hide(m_bootBtnPageP, instant);*/
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_bootLblUser); ++i)
|
||||
if(m_bootLblUser[i] != -1)
|
||||
m_btnMgr.hide(m_bootLblUser[i], instant);
|
||||
@ -82,12 +79,8 @@ static void hideBoot(bool instant, bool common)
|
||||
m_btnMgr.hide(m_bootLblUSBPort, instant);
|
||||
m_btnMgr.hide(m_bootBtnUSBPort, instant);
|
||||
|
||||
/* page 2 */
|
||||
m_btnMgr.hide(m_bootLblAsyncNet, instant);
|
||||
m_btnMgr.hide(m_bootBtnAsyncNet, instant);
|
||||
|
||||
m_btnMgr.hide(m_bootLblFtpOnBoot, instant);
|
||||
m_btnMgr.hide(m_bootBtnFtpOnBoot, instant);
|
||||
}
|
||||
|
||||
bool CMenu::_Boot(void)
|
||||
@ -109,7 +102,7 @@ bool CMenu::_Boot(void)
|
||||
m_btnMgr.up();
|
||||
else if(BTN_DOWN_PRESSED)
|
||||
m_btnMgr.down();
|
||||
else if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_bootBtnPageM)))
|
||||
/*else if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_bootBtnPageM)))
|
||||
{
|
||||
boot_curPage--;
|
||||
if(boot_curPage == 0) boot_curPage = boot_Pages;
|
||||
@ -124,7 +117,7 @@ bool CMenu::_Boot(void)
|
||||
if(BTN_RIGHT_PRESSED || BTN_PLUS_PRESSED)
|
||||
m_btnMgr.click(m_bootBtnPageP);
|
||||
_refreshBoot();
|
||||
}
|
||||
}*/
|
||||
else if(BTN_A_PRESSED)
|
||||
{
|
||||
if(m_btnMgr.selected(m_bootBtnBack))
|
||||
@ -166,11 +159,6 @@ bool CMenu::_Boot(void)
|
||||
m_cfg.setBool("GENERAL", "async_network", !m_cfg.getBool("GENERAL", "async_network", false));
|
||||
m_btnMgr.setText(m_bootBtnAsyncNet, m_cfg.getBool("GENERAL", "async_network", false) ? _t("on", L"On") : _t("off", L"Off"));
|
||||
}
|
||||
else if (m_btnMgr.selected(m_bootBtnFtpOnBoot))
|
||||
{
|
||||
m_cfg.setBool(FTP_DOMAIN, "auto_start", !m_cfg.getBool(FTP_DOMAIN, "auto_start", false));
|
||||
m_btnMgr.setText(m_bootBtnFtpOnBoot, m_cfg.getBool(FTP_DOMAIN, "auto_start") ? _t("on", L"On") : _t("off", L"Off"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(prev_load != cur_load || prev_ios != cur_ios)
|
||||
@ -191,7 +179,7 @@ bool CMenu::_Boot(void)
|
||||
void CMenu::_refreshBoot()
|
||||
{
|
||||
hideBoot(true, false);
|
||||
m_btnMgr.setText(m_bootLblPage, wfmt(L"%i / %i", boot_curPage, boot_Pages));
|
||||
//m_btnMgr.setText(m_bootLblPage, wfmt(L"%i / %i", boot_curPage, boot_Pages));
|
||||
if(boot_curPage == 1)
|
||||
{
|
||||
m_btnMgr.setText(m_bootBtnLoadCIOS, _optBoolToString(cur_load));
|
||||
@ -211,17 +199,10 @@ void CMenu::_refreshBoot()
|
||||
|
||||
m_btnMgr.show(m_bootLblUSBPort);
|
||||
m_btnMgr.show(m_bootBtnUSBPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
m_btnMgr.setText(m_bootBtnAsyncNet, m_cfg.getBool("GENERAL", "async_network", false) ? _t("on", L"On") : _t("off", L"Off"));
|
||||
m_btnMgr.setText(m_bootBtnFtpOnBoot, m_cfg.getBool(FTP_DOMAIN, "auto_start") ? _t("on", L"On") : _t("off", L"Off"));
|
||||
|
||||
m_btnMgr.show(m_bootLblAsyncNet);
|
||||
m_btnMgr.show(m_bootBtnAsyncNet);
|
||||
|
||||
m_btnMgr.show(m_bootLblFtpOnBoot);
|
||||
m_btnMgr.show(m_bootBtnFtpOnBoot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,7 +213,6 @@ void CMenu::_textBoot(void)
|
||||
m_btnMgr.setText(m_bootLblCIOSrev, _t("cfgbt3", L"Force cIOS Revision"));
|
||||
m_btnMgr.setText(m_bootLblUSBPort, _t("cfgbt4", L"USB Port"));
|
||||
m_btnMgr.setText(m_bootLblAsyncNet, _t("cfgp3", L"Init network on boot"));
|
||||
m_btnMgr.setText(m_bootLblFtpOnBoot, _t("cfgbt7", L"Start FTP Server on boot"));
|
||||
m_btnMgr.setText(m_bootBtnBack, _t("cfg10", L"Back"));
|
||||
}
|
||||
|
||||
@ -242,9 +222,9 @@ void CMenu::_initBoot(void)
|
||||
_addUserLabels(m_bootLblUser, ARRAY_SIZE(m_bootLblUser), "BOOT");
|
||||
m_bootLblTitle = _addTitle("BOOT/TITLE", theme.titleFont, L"", 0, 10, 640, 60, theme.titleFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE);
|
||||
m_bootBtnBack = _addButton("BOOT/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 48, theme.btnFontColor);
|
||||
m_bootLblPage = _addLabel("BOOT/PAGE_BTN", theme.btnFont, L"", 68, 400, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
/*m_bootLblPage = _addLabel("BOOT/PAGE_BTN", theme.btnFont, L"", 68, 400, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_bootBtnPageM = _addPicButton("BOOT/PAGE_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 20, 400, 48, 48);
|
||||
m_bootBtnPageP = _addPicButton("BOOT/PAGE_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 172, 400, 48, 48);
|
||||
m_bootBtnPageP = _addPicButton("BOOT/PAGE_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 172, 400, 48, 48);*/
|
||||
|
||||
m_bootLblLoadCIOS = _addLabel("BOOT/LOAD_CIOS", theme.lblFont, L"", 20, 125, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_bootBtnLoadCIOS = _addButton("BOOT/LOAD_CIOS_BTN", theme.btnFont, L"", 420, 130, 200, 48, theme.btnFontColor);
|
||||
@ -257,18 +237,14 @@ void CMenu::_initBoot(void)
|
||||
m_bootLblUSBPort = _addLabel("BOOT/USB_PORT", theme.lblFont, L"", 20, 245, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_bootBtnUSBPort = _addButton("BOOT/USB_PORT_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor);
|
||||
|
||||
/* page 2 */
|
||||
m_bootLblAsyncNet = _addLabel("BOOT/ASYNCNET", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_bootBtnAsyncNet = _addButton("BOOT/ASYNCNET_BTN", theme.btnFont, L"", 420, 310, 200, 48, theme.btnFontColor);
|
||||
|
||||
m_bootLblFtpOnBoot = _addLabel("BOOT/FTP", theme.lblFont, L"", 20, 245, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_bootBtnFtpOnBoot = _addButton("BOOT/FTP_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor);
|
||||
|
||||
_setHideAnim(m_bootLblTitle, "BOOT/TITLE", 0, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_bootBtnBack, "BOOT/BACK_BTN", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_bootLblPage, "BOOT/PAGE_BTN", 0, 0, 1.f, -1.f);
|
||||
/*_setHideAnim(m_bootLblPage, "BOOT/PAGE_BTN", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_bootBtnPageM, "BOOT/PAGE_MINUS", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_bootBtnPageP, "BOOT/PAGE_PLUS", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_bootBtnPageP, "BOOT/PAGE_PLUS", 0, 0, 1.f, -1.f);*/
|
||||
|
||||
_setHideAnim(m_bootLblLoadCIOS, "BOOT/LOAD_CIOS", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_bootBtnLoadCIOS, "BOOT/LOAD_CIOS_BTN", -50, 0, 1.f, 0.f);
|
||||
@ -284,9 +260,6 @@ void CMenu::_initBoot(void)
|
||||
_setHideAnim(m_bootLblAsyncNet, "BOOT/ASYNCNET", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_bootBtnAsyncNet, "BOOT/ASYNCNET_BTN", -50, 0, 1.f, 0.f);
|
||||
|
||||
_setHideAnim(m_bootLblFtpOnBoot, "BOOT/FTP", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_bootBtnFtpOnBoot, "BOOT/FTP_BTN", -50, 0, 1.f, 0.f);
|
||||
|
||||
hideBoot(true, true);
|
||||
_textBoot();
|
||||
}
|
||||
|
@ -21,9 +21,11 @@ TexData m_categoryBg;
|
||||
vector<char> m_categories;
|
||||
static u8 curPage;
|
||||
u8 lastBtn;
|
||||
const char *catSettings;
|
||||
string id;
|
||||
string catDomain;
|
||||
const char *catSettings = NULL;
|
||||
const char *id = NULL;
|
||||
const char *pluginID = NULL;
|
||||
const char *catDomain = NULL;
|
||||
char tmp[64];
|
||||
bool gameSet;
|
||||
|
||||
void CMenu::_hideCategorySettings(bool instant)
|
||||
@ -102,7 +104,6 @@ void CMenu::_updateCheckboxes(void)
|
||||
default:
|
||||
m_btnMgr.show(m_categoryBtnCatReq[i]);
|
||||
}
|
||||
|
||||
m_btnMgr.setText(m_categoryLblCat[i], m_cat.getWString("GENERAL", fmt("cat%d",j), wfmt(L"Category %i",j).c_str()));
|
||||
m_btnMgr.show(m_categoryLblCat[i]);
|
||||
}
|
||||
@ -130,10 +131,24 @@ void CMenu::_getIDCats(void)
|
||||
catDomain = "WII";
|
||||
break;
|
||||
default:
|
||||
catDomain = (m_plugin.GetPluginName(m_plugin.GetPluginPosition(hdr->settings[0]))).toUTF8();
|
||||
catDomain = m_plugin.PluginMagicWord;
|
||||
}
|
||||
id = CoverFlow.getPathId(hdr, false);
|
||||
const char *idCats = m_cat.getString(catDomain, id, "").c_str();
|
||||
memset(tmp, 0, 64);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
wcstombs(tmp, hdr->title, 64);
|
||||
pluginID = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = hdr->id;
|
||||
if(hdr->type == TYPE_GC_GAME && hdr->settings[0] == 1) /* disc 2 */
|
||||
{
|
||||
strcat(tmp, fmt("%.6s_2", hdr->id));
|
||||
id = tmp;
|
||||
}
|
||||
}
|
||||
const char *idCats = m_cat.getString(catDomain, hdr->type == TYPE_PLUGIN? pluginID : id).c_str();
|
||||
u8 numIdCats = strlen(idCats);
|
||||
if(numIdCats != 0)
|
||||
{
|
||||
@ -148,6 +163,7 @@ void CMenu::_getIDCats(void)
|
||||
|
||||
void CMenu::_setIDCats(void)
|
||||
{
|
||||
const dir_discHdr *hdr = CoverFlow.getHdr();
|
||||
string newIdCats = "";
|
||||
for(int i = 1; i < m_max_categories; i++)
|
||||
{
|
||||
@ -157,7 +173,7 @@ void CMenu::_setIDCats(void)
|
||||
newIdCats = newIdCats + cCh;
|
||||
}
|
||||
}
|
||||
m_cat.setString(catDomain, id, newIdCats);
|
||||
m_cat.setString(catDomain, hdr->type == TYPE_PLUGIN? pluginID : id, newIdCats);
|
||||
}
|
||||
|
||||
void CMenu::_CategorySettings(bool fromGameSet)
|
||||
@ -253,9 +269,12 @@ void CMenu::_CategorySettings(bool fromGameSet)
|
||||
m_cat.setString("GENERAL", "required_categories", newReqCats);
|
||||
}
|
||||
else
|
||||
{
|
||||
_setIDCats();
|
||||
m_load_view = true;
|
||||
}
|
||||
|
||||
m_cat.save();
|
||||
//m_cat.save();
|
||||
break;
|
||||
}
|
||||
else if(BTN_UP_PRESSED)
|
||||
@ -386,7 +405,7 @@ void CMenu::_initCategorySettingsMenu()
|
||||
m_categoryLblPage = _addLabel("CATEGORY/PAGE_BTN", theme.btnFont, L"", 68, 400, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_categoryBtnPageP = _addPicButton("CATEGORY/PAGE_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 172, 400, 48, 48);
|
||||
m_categoryBtnBack = _addButton("CATEGORY/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 48, theme.btnFontColor);
|
||||
m_categoryBtnClear = _addButton("CATEGORY/CLEAR_BTN", theme.btnFont, L"", 220, 400, 200, 48, theme.btnFontColor);
|
||||
m_categoryBtnClear = _addButton("CATEGORY/CLEAR_BTN", theme.btnFont, L"", 230, 400, 180, 48, theme.btnFontColor);
|
||||
for(u8 i = 1; i < 6; ++i)
|
||||
{ // left half
|
||||
m_categoryBtnCat[i] = _addPicButton(fmt("CATEGORY/CAT_%i_BTN", i), theme.checkboxoff, theme.checkboxoffs, 30, (39+i*58), 44, 48);
|
||||
|
@ -52,22 +52,23 @@ void CMenu::_showConfig(void)
|
||||
|
||||
if(!m_locked)
|
||||
{
|
||||
m_btnMgr.show(m_configLblDownload);
|
||||
m_btnMgr.show(m_configBtnDownload);
|
||||
|
||||
currentPartition = m_cfg.getInt(_domainFromView(), "partition", 0);
|
||||
const char *partitionname = DeviceName[currentPartition];
|
||||
m_btnMgr.setText(m_configLblPartition, upperCase(partitionname));
|
||||
m_btnMgr.show(m_configLblPartitionName);
|
||||
m_btnMgr.show(m_configLblPartition);
|
||||
m_btnMgr.show(m_configBtnPartitionP);
|
||||
m_btnMgr.show(m_configBtnPartitionM);
|
||||
m_btnMgr.show(m_configLblDownload);
|
||||
m_btnMgr.show(m_configBtnDownload);
|
||||
|
||||
m_btnMgr.show(m_configLblCfg4);
|
||||
m_btnMgr.show(m_configBtnCfg4);
|
||||
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_configLblUser); ++i)
|
||||
if(m_configLblUser[i] != -1)
|
||||
m_btnMgr.show(m_configLblUser[i]);
|
||||
|
||||
const char *partitionname = DeviceName[m_cfg.getInt(_domainFromView(), "partition", 0)];
|
||||
m_btnMgr.setText(m_configLblPartition, upperCase(partitionname));
|
||||
|
||||
m_btnMgr.show(m_configLblCfg4);
|
||||
m_btnMgr.show(m_configBtnCfg4);
|
||||
}
|
||||
m_btnMgr.show(m_configLblParental);
|
||||
m_btnMgr.show(m_locked ? m_configBtnUnlock : m_configBtnSetCode);
|
||||
@ -138,14 +139,10 @@ int CMenu::_configCommon(void)
|
||||
int CMenu::_config1(void)
|
||||
{
|
||||
int change = CONFIG_PAGE_NO_CHANGE;
|
||||
|
||||
SetupInput();
|
||||
|
||||
s32 bCurrentPartition = currentPartition;
|
||||
|
||||
//gprintf("Current Partition: %d\n", currentPartition);
|
||||
|
||||
_showConfig();
|
||||
_textConfig();
|
||||
s32 bCurrentPartition = currentPartition;
|
||||
|
||||
while(!m_exit)
|
||||
{
|
||||
@ -160,11 +157,9 @@ int CMenu::_config1(void)
|
||||
if (m_btnMgr.selected(m_configBtnDownload))
|
||||
{
|
||||
m_load_view = true;
|
||||
CoverFlow.stopCoverLoader(true);
|
||||
_hideConfig();
|
||||
_download();
|
||||
_showConfig();
|
||||
CoverFlow.startCoverLoader();
|
||||
}
|
||||
else if (m_btnMgr.selected(m_configBtnUnlock))
|
||||
{
|
||||
@ -200,14 +195,9 @@ int CMenu::_config1(void)
|
||||
else if (m_btnMgr.selected(m_configBtnCfg4))
|
||||
{
|
||||
m_load_view = true;
|
||||
CoverFlow.stopCoverLoader(true);
|
||||
_hideConfig();
|
||||
if(m_current_view != COVERFLOW_PLUGIN || m_use_source)
|
||||
_NandEmuCfg();
|
||||
else
|
||||
_PluginSettings();
|
||||
_NandEmuCfg();
|
||||
_showConfig();
|
||||
CoverFlow.startCoverLoader();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -269,14 +259,6 @@ void CMenu::_textConfig(void)
|
||||
m_btnMgr.setText(m_configBtnSetCode, _t("cfg7", L"Set code"));
|
||||
m_btnMgr.setText(m_configLblPartitionName, _t("cfgp1", L"Game Partition"));
|
||||
m_btnMgr.setText(m_configBtnBack, _t("cfg10", L"Back"));
|
||||
if(m_current_view != COVERFLOW_PLUGIN || m_use_source)
|
||||
{
|
||||
m_btnMgr.setText(m_configLblCfg4, _t("cfg13", L"NAND Emulation Settings"));
|
||||
m_btnMgr.setText(m_configBtnCfg4, _t("cfg14", L"Set"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_btnMgr.setText(m_configLblCfg4, _t("cfg15", L"Plugins"));
|
||||
m_btnMgr.setText(m_configBtnCfg4, _t("cfg16", L"Select"));
|
||||
}
|
||||
m_btnMgr.setText(m_configLblCfg4, _t("cfg13", L"NAND Emulation Settings"));
|
||||
m_btnMgr.setText(m_configBtnCfg4, _t("cfg14", L"Set"));
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ void CMenu::_initGameSettingsMenu()
|
||||
_setHideAnim(m_gameSettingsLblPage, "GAME_SETTINGS/PAGE_BTN", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_gameSettingsBtnPageM, "GAME_SETTINGS/PAGE_MINUS", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_gameSettingsBtnPageP, "GAME_SETTINGS/PAGE_PLUS", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_gameSettingsBtnBack, "GAME_SETTINGS/BACK_BTN", 0, 200, 1.f, -1.f);
|
||||
_setHideAnim(m_gameSettingsBtnBack, "GAME_SETTINGS/BACK_BTN", 0, 0, 1.f, -1.f);
|
||||
|
||||
_hideGameSettings(true);
|
||||
_textGameSettings();
|
||||
|
@ -115,26 +115,31 @@ void CMenu::_CfgSrc(void)
|
||||
break;
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnEnableSF))
|
||||
{
|
||||
m_cfg.setBool("SOURCEFLOW", "enabled", !m_cfg.getBool("SOURCEFLOW", "enabled", false));
|
||||
m_sourceflow = !m_sourceflow;
|
||||
m_cfg.setBool("SOURCEFLOW", "enabled", m_sourceflow);
|
||||
m_cfg.setBool("GENERAL", "multisource", false);
|
||||
m_btnMgr.setText(m_cfgsrcBtnEnableSF, m_cfg.getBool("SOURCEFLOW", "enabled") ? _t("on", L"On") : _t("off", L"Off"));
|
||||
}
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnSmallbox) && m_sourceflow)
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnSmallbox))
|
||||
{
|
||||
m_load_view = true;
|
||||
if(m_sourceflow)
|
||||
m_load_view = true;
|
||||
fsop_deleteFolder(fmt("%s/sourceflow", m_cacheDir.c_str()));
|
||||
m_cfg.setBool("SOURCEFLOW", "smallbox", !m_cfg.getBool("SOURCEFLOW", "smallbox", false));
|
||||
m_btnMgr.setText(m_cfgsrcBtnSmallbox, m_cfg.getBool("SOURCEFLOW", "smallbox") ? _t("on", L"On") : _t("off", L"Off"));
|
||||
}
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnClearSF) && m_sourceflow)
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnClearSF))
|
||||
{
|
||||
m_cfg.setBool("SOURCEFLOW", "update_cache", true);
|
||||
m_load_view = true;
|
||||
if(m_sourceflow)
|
||||
m_load_view = true;
|
||||
}
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnMultisource) && !m_sourceflow)
|
||||
else if (m_btnMgr.selected(m_cfgsrcBtnMultisource))
|
||||
{
|
||||
m_cfg.setBool("GENERAL", "multisource", !m_cfg.getBool("GENERAL", "multisource", false));
|
||||
m_multisource = !m_multisource;
|
||||
m_cfg.setBool("GENERAL", "multisource", m_multisource);
|
||||
m_cfg.setBool("SOURCEFLOW", "enabled", false);
|
||||
m_btnMgr.setText(m_cfgsrcBtnMultisource, m_cfg.getBool("GENERAL", "multisource") ? _t("on", L"On") : _t("off", L"Off"));
|
||||
m_multisource = m_cfg.getBool("GENERAL", "multisource", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2018,16 +2018,10 @@ int CMenu::_gametdbDownloaderAsync()
|
||||
|
||||
// Update cache
|
||||
UpdateCache();
|
||||
|
||||
LWP_MutexLock(m_mutex);
|
||||
_setThrdMsg(_t("dlmsg26", L"Updating cache..."), 0.f);
|
||||
LWP_MutexUnlock(m_mutex);
|
||||
|
||||
m_GameTDBAvailable = true;
|
||||
|
||||
m_load_view = true;
|
||||
//_loadList();
|
||||
//_initCF();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -440,5 +440,7 @@ const char *CMenu::_FolderExplorer(const char *startPath)
|
||||
strcat(dir, "/");
|
||||
_Explorer();
|
||||
folderExplorer = false;
|
||||
if(strrchr(folderPath, '/') != NULL)
|
||||
*strrchr(folderPath, '/') = '\0';
|
||||
return folderPath;
|
||||
}
|
||||
|
@ -1,148 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2013 FIX94
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "menu.hpp"
|
||||
#include "network/net.h"
|
||||
#include "network/ftp.h"
|
||||
#include "network/http.h"
|
||||
#include "network/gcard.h"
|
||||
#include "network/FTP_Dir.hpp"
|
||||
|
||||
s16 m_ftpLblTitle;
|
||||
s16 m_ftpBtnBack;
|
||||
s16 m_ftpBtnToggle;
|
||||
s16 m_ftpLblInfo;
|
||||
s16 m_ftpLblUser[4];
|
||||
|
||||
void CMenu::_updateFTP(void)
|
||||
{
|
||||
_hideFTP(true);
|
||||
if(m_ftp_inited == true)
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = net_gethostip();
|
||||
m_btnMgr.hide(m_wbfsLblDialog, true);
|
||||
m_btnMgr.setText(m_ftpLblTitle, wfmt(_t("dlmsg28", L"Running FTP Server on %s:%d"), inet_ntoa(addr), ftp_server_port));
|
||||
m_btnMgr.show(m_ftpLblTitle);
|
||||
m_btnMgr.setText(m_ftpBtnToggle, _t("ftp2", L"Stop"));
|
||||
m_btnMgr.show(m_ftpLblInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_btnMgr.hide(m_ftpLblTitle, true);
|
||||
m_btnMgr.setText(m_wbfsLblDialog, _t("dlmsg29", L"FTP Server is currently stopped."));
|
||||
m_btnMgr.setText(m_ftpBtnToggle, _t("ftp1", L"Start"));
|
||||
m_btnMgr.show(m_wbfsLblDialog);
|
||||
}
|
||||
_showFTP();
|
||||
}
|
||||
|
||||
void CMenu::_FTP(void)
|
||||
{
|
||||
_updateFTP();
|
||||
while(!m_exit)
|
||||
{
|
||||
_mainLoopCommon();
|
||||
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
|
||||
break;
|
||||
else if(BTN_A_PRESSED)
|
||||
{
|
||||
if(m_btnMgr.selected(m_ftpBtnBack))
|
||||
break;
|
||||
else if(m_btnMgr.selected(m_ftpBtnToggle))
|
||||
{
|
||||
if(m_ftp_inited == true)
|
||||
{
|
||||
ftp_endTread();
|
||||
m_init_ftp = false;
|
||||
m_ftp_inited = false;
|
||||
init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko);
|
||||
ftp_dbg_print_update();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_init_ftp = true;
|
||||
init_network = true;
|
||||
if(networkInit == false)
|
||||
{
|
||||
gprintf("no net init yet\n");
|
||||
_netInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
gprintf("net already inited, just start server\n");
|
||||
m_ftp_inited = ftp_startThread();
|
||||
}
|
||||
}
|
||||
_updateFTP();
|
||||
}
|
||||
}
|
||||
if(ftp_dbg_print_update())
|
||||
{
|
||||
m_btnMgr.setText(m_ftpLblInfo, wfmt(L"%s%s%s%s%s%s", ftp_get_prints(5), ftp_get_prints(4),
|
||||
ftp_get_prints(3), ftp_get_prints(2), ftp_get_prints(1), ftp_get_prints(0)));
|
||||
}
|
||||
}
|
||||
m_btnMgr.hide(m_wbfsLblDialog);
|
||||
_hideFTP();
|
||||
}
|
||||
|
||||
void CMenu::_showFTP(void)
|
||||
{
|
||||
m_btnMgr.show(m_ftpBtnToggle);
|
||||
m_btnMgr.show(m_ftpBtnBack);
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_ftpLblUser); ++i)
|
||||
if(m_ftpLblUser[i] != -1)
|
||||
m_btnMgr.show(m_ftpLblUser[i]);
|
||||
}
|
||||
|
||||
void CMenu::_hideFTP(bool instant)
|
||||
{
|
||||
m_btnMgr.hide(m_ftpLblTitle, instant);
|
||||
m_btnMgr.hide(m_ftpBtnToggle, instant);
|
||||
m_btnMgr.hide(m_ftpBtnBack, instant);
|
||||
m_btnMgr.hide(m_ftpLblInfo, instant);
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_ftpLblUser); ++i)
|
||||
if(m_ftpLblUser[i] != -1)
|
||||
m_btnMgr.hide(m_ftpLblUser[i], instant);
|
||||
}
|
||||
|
||||
void CMenu::_initFTP(void)
|
||||
{
|
||||
_addUserLabels(m_ftpLblUser, ARRAY_SIZE(m_ftpLblUser), "FTP");
|
||||
|
||||
m_ftpLblTitle = _addTitle("FTP/TITLE", theme.titleFont, L"", 0, 10, 640, 60, theme.titleFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE);
|
||||
m_ftpBtnToggle = _addButton("FTP/TOGGLE_BTN", theme.btnFont, L"", 20, 400, 200, 48, theme.btnFontColor);
|
||||
m_ftpBtnBack = _addButton("FTP/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 48, theme.btnFontColor);
|
||||
m_ftpLblInfo = _addText("FTP/INFO", theme.txtFont, L"", 40, 115, 560, 270, theme.txtFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_TOP);
|
||||
|
||||
_setHideAnim(m_ftpLblTitle, "FTP/TITLE", 0, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_ftpBtnToggle, "FTP/TOGGLE_BTN", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_ftpBtnBack, "FTP/BACK_BTN", 0, 0, 1.f, -1.f);
|
||||
_setHideAnim(m_ftpLblInfo, "FTP/INFO", 0, 100, 0.f, 0.f);
|
||||
|
||||
_textFTP();
|
||||
_hideFTP(true);
|
||||
}
|
||||
|
||||
void CMenu::_textFTP(void)
|
||||
{
|
||||
m_btnMgr.setText(m_ftpLblTitle, L"");
|
||||
m_btnMgr.setText(m_ftpBtnToggle, L"");
|
||||
m_btnMgr.setText(m_ftpBtnBack, _t("cfg10", L"Back"));
|
||||
m_btnMgr.setText(m_ftpLblInfo, L"");
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ static const char *getVideoPath(const string &videoDir, const char *videoId)
|
||||
|
||||
static const char *getVideoDefaultPath(const string &videoDir)
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", CoverFlow.getHdr()->settings[0]), 8);
|
||||
//strncpy(m_plugin.PluginMagicWord, fmt("%08x", CoverFlow.getHdr()->settings[0]), 8);
|
||||
const char *videoPath = fmt("%s/%s", videoDir.c_str(), m_plugin.PluginMagicWord);
|
||||
return videoPath;
|
||||
}
|
||||
@ -436,6 +436,29 @@ void CMenu::_game(bool launch)
|
||||
dir_discHdr *hdr = (dir_discHdr*)MEM2_alloc(sizeof(dir_discHdr));
|
||||
memcpy(hdr, CoverFlow.getHdr(), sizeof(dir_discHdr));
|
||||
|
||||
const char *id = NULL;
|
||||
char tmp1[74];// title plus / plus magic#
|
||||
memset(tmp1, 0, 74);
|
||||
char tmp2[64];
|
||||
memset(tmp2, 0, 64);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", hdr->settings[0]), 8);
|
||||
wcstombs(tmp2, hdr->title, 64);
|
||||
strcat(tmp1, m_plugin.PluginMagicWord);
|
||||
strcat(tmp1, fmt("/%s", tmp2));
|
||||
id = tmp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = hdr->id;
|
||||
if(hdr->type == TYPE_GC_GAME && hdr->settings[0] == 1) /* disc 2 */
|
||||
{
|
||||
strcat(tmp1, fmt("%.6s_2", hdr->id));
|
||||
id = tmp1;
|
||||
}
|
||||
}
|
||||
|
||||
m_zoom_banner = m_cfg.getBool(_domainFromView(), "show_full_banner", false);
|
||||
if(NoGameID(hdr->type))
|
||||
{
|
||||
@ -448,7 +471,6 @@ void CMenu::_game(bool launch)
|
||||
if(m_banner.GetZoomSetting() != m_zoom_banner)
|
||||
m_banner.ToggleZoom();
|
||||
|
||||
m_gcfg1.load(fmt("%s/" GAME_SETTINGS1_FILENAME, m_settingsDir.c_str()));
|
||||
s8 startGameSound = -7;
|
||||
SetupInput();
|
||||
|
||||
@ -494,7 +516,6 @@ void CMenu::_game(bool launch)
|
||||
v.y = min(max(-15.f, v.y + step), 15.f);
|
||||
}
|
||||
CoverFlow.setCoverFlipPos(v);
|
||||
//CoverFlow.flip(true, true);
|
||||
}
|
||||
if(BTN_B_PRESSED && !m_locked && (m_btnMgr.selected(m_gameBtnFavoriteOn) || m_btnMgr.selected(m_gameBtnFavoriteOff)))
|
||||
{
|
||||
@ -520,16 +541,22 @@ void CMenu::_game(bool launch)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(BTN_PLUS_PRESSED && !coverFlipped && m_GameTDBAvailable && !NoGameID(hdr->type))
|
||||
else if(BTN_PLUS_PRESSED && !NoGameID(hdr->type) && !coverFlipped)
|
||||
{
|
||||
_hideGame();
|
||||
m_banner.SetShowBanner(false);
|
||||
m_gameSelected = true;// guess its reset to true to keep game/banner sound playing (if it is) during gameinfo menu
|
||||
_gameinfo();
|
||||
_showGame();
|
||||
m_banner.SetShowBanner(true);
|
||||
if(!m_gameSound.IsPlaying())
|
||||
startGameSound = -6;
|
||||
GameTDB m_gametdb;
|
||||
m_gametdb.OpenFile(fmt("%s/wiitdb.xml", m_settingsDir.c_str()));
|
||||
if(m_gametdb.IsLoaded())
|
||||
{
|
||||
_hideGame();
|
||||
m_banner.SetShowBanner(false);
|
||||
m_gameSelected = true;// guess its reset to true to keep game/banner sound playing (if it is) during gameinfo menu
|
||||
_gameinfo();
|
||||
m_gametdb.CloseFile();
|
||||
_showGame();
|
||||
m_banner.SetShowBanner(true);
|
||||
if(!m_gameSound.IsPlaying())
|
||||
startGameSound = -6;
|
||||
}
|
||||
}
|
||||
else if(BTN_MINUS_PRESSED && !coverFlipped)
|
||||
{
|
||||
@ -558,43 +585,50 @@ void CMenu::_game(bool launch)
|
||||
{
|
||||
if(m_btnMgr.selected(m_mainBtnQuit))
|
||||
break;
|
||||
else if(m_btnMgr.selected(m_gameBtnDelete))
|
||||
else if(m_btnMgr.selected(m_gameBtnDelete) && !m_locked)
|
||||
{
|
||||
if(!m_locked)
|
||||
_hideGame();
|
||||
m_banner.SetShowBanner(false);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
_hideGame();
|
||||
m_banner.SetShowBanner(false);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
const char *wfcPath = NULL;
|
||||
const char *coverDir = NULL;
|
||||
if(m_cfg.getBool(PLUGIN_DOMAIN, "subfolder_cache"))
|
||||
coverDir = m_plugin.GetCoverFolderName(hdr->settings[0]);
|
||||
if(coverDir == NULL || strlen(coverDir) == 0)
|
||||
wfcPath = fmt("%s/%s.wfc", m_cacheDir.c_str(), CoverFlow.getPathId(hdr, false));
|
||||
else
|
||||
wfcPath = fmt("%s/%s/%s.wfc", m_cacheDir.c_str(), coverDir, CoverFlow.getPathId(hdr, false));
|
||||
fsop_deleteFile(wfcPath);
|
||||
m_load_view = true;
|
||||
}
|
||||
const char *wfcPath = NULL;
|
||||
const char *coverDir = NULL;
|
||||
if(m_cfg.getBool(PLUGIN_DOMAIN, "subfolder_cache"))
|
||||
coverDir = m_plugin.GetCoverFolderName(hdr->settings[0]);
|
||||
if(coverDir == NULL || strlen(coverDir) == 0)
|
||||
wfcPath = fmt("%s/%s.wfc", m_cacheDir.c_str(), CoverFlow.getPathId(hdr, true));
|
||||
else
|
||||
{
|
||||
if(_wbfsOp(WO_REMOVE_GAME))
|
||||
{
|
||||
_cleanupBanner();
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_banner.SetShowBanner(true);
|
||||
if(!m_gameSound.IsPlaying())
|
||||
startGameSound = -6;
|
||||
_showGame();
|
||||
wfcPath = fmt("%s/%s/%s.wfc", m_cacheDir.c_str(), coverDir, CoverFlow.getPathId(hdr, true));
|
||||
fsop_deleteFile(wfcPath);
|
||||
m_load_view = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_wbfsOp(WO_REMOVE_GAME))
|
||||
{
|
||||
_cleanupBanner();
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_banner.SetShowBanner(true);
|
||||
if(!m_gameSound.IsPlaying())
|
||||
startGameSound = -6;
|
||||
_showGame();
|
||||
}
|
||||
else if(m_btnMgr.selected(m_gameBtnFavoriteOn) || m_btnMgr.selected(m_gameBtnFavoriteOff))
|
||||
m_gcfg1.setBool("FAVORITES", CoverFlow.getPathId(hdr, false), !m_gcfg1.getBool("FAVORITES", CoverFlow.getPathId(hdr, false), false));
|
||||
{
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
m_gcfg1.setBool("FAVORITES_PLUGINS", id, !m_gcfg1.getBool("FAVORITES_PLUGINS", id, false));
|
||||
else
|
||||
m_gcfg1.setBool("FAVORITES", id, !m_gcfg1.getBool("FAVORITES", id, false));
|
||||
}
|
||||
else if(m_btnMgr.selected(m_gameBtnAdultOn) || m_btnMgr.selected(m_gameBtnAdultOff))
|
||||
m_gcfg1.setBool("ADULTONLY", CoverFlow.getPathId(hdr, false), !m_gcfg1.getBool("ADULTONLY", CoverFlow.getPathId(hdr, false), false));
|
||||
{
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
m_gcfg1.setBool("ADULTONLY_PLUGINS", id, !m_gcfg1.getBool("ADULTONLY_PLUGINS", id, false));
|
||||
else
|
||||
m_gcfg1.setBool("ADULTONLY", id, !m_gcfg1.getBool("ADULTONLY", id, false));
|
||||
}
|
||||
else if(m_btnMgr.selected(m_gameBtnBack) || m_btnMgr.selected(m_gameBtnBackFull))
|
||||
{
|
||||
_cleanupBanner();
|
||||
@ -630,8 +664,7 @@ void CMenu::_game(bool launch)
|
||||
MusicPlayer.Stop();
|
||||
_cleanupBanner();
|
||||
m_gcfg2.load(fmt("%s/" GAME_SETTINGS2_FILENAME, m_settingsDir.c_str()));
|
||||
// change to current game's partition and set last_view for recall later
|
||||
m_cfg.setInt("GENERAL", "last_view", m_current_view);
|
||||
// change to current game's partition and set categories start page for recall later
|
||||
m_cfg.setInt("GENERAL", "cat_startpage", m_catStartPage);
|
||||
switch(hdr->type)
|
||||
{
|
||||
@ -649,20 +682,15 @@ void CMenu::_game(bool launch)
|
||||
currentPartition = m_cfg.getInt(WII_DOMAIN, "partition", 1);
|
||||
break;
|
||||
default:
|
||||
m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(enabledPluginsCount == 1)
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", hdr->settings[0]), 8);
|
||||
currentPartition = m_cfg.getInt("PLUGINS_PARTITION", m_plugin.PluginMagicWord, 1);
|
||||
m_cfg.setInt(PLUGIN_DOMAIN, "partition", currentPartition);
|
||||
}
|
||||
currentPartition = m_cfg.getInt(PLUGIN_DOMAIN, "partition", 1);
|
||||
int romsPartition = m_plugin.GetRomPartition(m_plugin.GetPluginPosition(hdr->settings[0]));
|
||||
if(romsPartition < 0)
|
||||
romsPartition = m_cfg.getInt(PLUGIN_DOMAIN, "partition", 0);
|
||||
currentPartition = romsPartition;
|
||||
break;
|
||||
}
|
||||
/* Get Banner Title for Playlog */
|
||||
CurrentBanner.ClearBanner();
|
||||
NANDemuView = false;
|
||||
if(hdr->type == TYPE_EMUCHANNEL) NANDemuView = true;
|
||||
NANDemuView = hdr->type == TYPE_EMUCHANNEL;
|
||||
if(hdr->type == TYPE_CHANNEL || hdr->type == TYPE_EMUCHANNEL)
|
||||
{
|
||||
u64 chantitle = CoverFlow.getChanTitle();
|
||||
@ -738,16 +766,39 @@ void CMenu::_game(bool launch)
|
||||
CoverFlow.left();
|
||||
startGameSound = -10;
|
||||
}
|
||||
if(startGameSound == -10)
|
||||
if(startGameSound == -10)// if -10 then we moved to new cover
|
||||
{
|
||||
m_gameSelected = false; // deselect game if moved to new cover
|
||||
_setBg(m_gameBg, m_gameBgLQ);
|
||||
memcpy(hdr, CoverFlow.getHdr(), sizeof(dir_discHdr));
|
||||
memcpy(hdr, CoverFlow.getHdr(), sizeof(dir_discHdr));// get new game header
|
||||
memset(tmp1, 0, 74);
|
||||
memset(tmp2, 0, 64);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", hdr->settings[0]), 8);
|
||||
wcstombs(tmp2, hdr->title, 64);
|
||||
strcat(tmp1, m_plugin.PluginMagicWord);
|
||||
strcat(tmp1, fmt("/%s", tmp2));
|
||||
id = tmp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = hdr->id;
|
||||
if(hdr->type == TYPE_GC_GAME && hdr->settings[0] == 1) /* disc 2 */
|
||||
{
|
||||
strcat(tmp1, fmt("%.6s_2", hdr->id));
|
||||
id = tmp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_show_zone_game && !m_zoom_banner)
|
||||
{
|
||||
bool b = m_gcfg1.getBool("FAVORITES", CoverFlow.getPathId(hdr, false), false);
|
||||
bool b;
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
b = m_gcfg1.getBool("FAVORITES_PLUGINS", id, false);
|
||||
else
|
||||
b = m_gcfg1.getBool("FAVORITES", id, false);
|
||||
m_btnMgr.show(b ? m_gameBtnFavoriteOn : m_gameBtnFavoriteOff);
|
||||
m_btnMgr.hide(b ? m_gameBtnFavoriteOff : m_gameBtnFavoriteOn);
|
||||
m_btnMgr.show(m_gameBtnPlay);
|
||||
@ -770,7 +821,10 @@ void CMenu::_game(bool launch)
|
||||
}
|
||||
if(!m_locked)
|
||||
{
|
||||
b = m_gcfg1.getBool("ADULTONLY", CoverFlow.getPathId(hdr, false), false);
|
||||
if(hdr->type == TYPE_PLUGIN)
|
||||
b = m_gcfg1.getBool("ADULTONLY_PLUGINS", id, false);
|
||||
else
|
||||
b = m_gcfg1.getBool("ADULTONLY", id, false);
|
||||
m_btnMgr.show(b ? m_gameBtnAdultOn : m_gameBtnAdultOff);
|
||||
m_btnMgr.hide(b ? m_gameBtnAdultOff : m_gameBtnAdultOn);
|
||||
m_btnMgr.show(m_gameBtnSettings);
|
||||
@ -813,7 +867,6 @@ void CMenu::_game(bool launch)
|
||||
_loadCFLayout(cf_version, true);
|
||||
CoverFlow.applySettings();
|
||||
}
|
||||
m_gcfg1.save(true);
|
||||
_hideGame();
|
||||
}
|
||||
|
||||
@ -876,7 +929,7 @@ void CMenu::_launch(const dir_discHdr *hdr)
|
||||
u32 title_len_no_ext = 0;
|
||||
const char *path = NULL;
|
||||
//example rom path - sd:/roms/super mario bros.zip
|
||||
//example scummvm path - games/monkey island.exe
|
||||
//example scummvm path - kq1-coco3
|
||||
if(strchr(launchHdr.path, ':') != NULL)//it's a rom path
|
||||
{
|
||||
//check if music player plugin, if so launch wiiflow's music player
|
||||
@ -896,16 +949,13 @@ void CMenu::_launch(const dir_discHdr *hdr)
|
||||
}
|
||||
else //it's a scummvm game
|
||||
{
|
||||
path = launchHdr.path;
|
||||
wcstombs(title, launchHdr.title, 63);
|
||||
path = launchHdr.path;// kq1-coco3
|
||||
wcstombs(title, launchHdr.title, 63);// King's Quest I: Quest for the Crown (CoCo3/English)
|
||||
}
|
||||
m_cfg.setString(PLUGIN_DOMAIN, "current_item", title);
|
||||
|
||||
const char *device = (currentPartition == 0 ? "sd" : (DeviceHandle.GetFSType(currentPartition) == PART_FS_NTFS ? "ntfs" : "usb"));
|
||||
/* this is weird - he sets the return to loader to be dev:/wiiflow/plugins/WiiFlowLoader.dol
|
||||
but there is no such dol in the plugins directory and WiiFlowLoader.dol is really a hidden channel
|
||||
on the system menu. This is set because some plugins require a arg for loader dol and even though
|
||||
this isn't real it fills the argument needed. */
|
||||
// I believe the loader is set just in case the user is using a old plugin where the arguments line still requires loader
|
||||
const char *loader = fmt("%s:/%s/WiiFlowLoader.dol", device, strchr(m_pluginsDir.c_str(), '/') + 1);
|
||||
|
||||
vector<string> arguments = m_plugin.CreateArgs(device, path, title, loader, title_len_no_ext, launchHdr.settings[0]);
|
||||
@ -996,8 +1046,8 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
|
||||
}
|
||||
else if(loader == 1)
|
||||
{
|
||||
u8 emuMC = min((u32)m_gcfg2.getInt(id, "emu_memcard", m_cfg.getInt(GC_DOMAIN, "emu_memcard", 1)), ARRAY_SIZE(CMenu::_NinEmuCard) - 1u);
|
||||
emuMC = (emuMC == 0) ? m_cfg.getInt(GC_DOMAIN, "emu_memcard", 1) : emuMC-1;
|
||||
u8 emuMC = min((u32)m_gcfg2.getInt(id, "emu_memcard", m_cfg.getInt(GC_DOMAIN, "emu_memcard", 2)), ARRAY_SIZE(CMenu::_NinEmuCard) - 1u);
|
||||
emuMC = (emuMC == 0) ? m_cfg.getInt(GC_DOMAIN, "emu_memcard", 2) : emuMC-1;
|
||||
bool usb_hid = m_gcfg2.getBool(id, "usb_hid", m_cfg.getBool(GC_DOMAIN, "usb_hid", false));
|
||||
bool native_ctl = m_gcfg2.getBool(id, "native_ctl", m_cfg.getBool(GC_DOMAIN, "native_ctl", false));
|
||||
bool deflicker = m_gcfg2.getBool(id, "Deflicker", m_cfg.getBool(GC_DOMAIN, "Deflicker", false));
|
||||
@ -1394,34 +1444,8 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
if(emuPartition < 0)//if savepartition and/or nand folder no good
|
||||
{
|
||||
_hideWaitMessage();
|
||||
while(true)
|
||||
{
|
||||
if(!_AutoCreateNand())//change partition, extract nand, or disable emunand save
|
||||
{//if disable
|
||||
emulate_mode = 0;
|
||||
m_gcfg2.setInt(id, "emulate_save", 1);
|
||||
break;
|
||||
}
|
||||
emuPartition = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
||||
if(emulate_mode == 3)//full
|
||||
{
|
||||
if(_TestEmuNand(m_cfg.getInt(WII_DOMAIN, "savepartition"), emuPath.c_str(), true))
|
||||
{
|
||||
//emuPartition = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else//gamesave or regionswitch
|
||||
{
|
||||
if(!_TestEmuNand(emuPartition, emuPath.c_str(), false))
|
||||
{
|
||||
NandHandle.CreatePath(fmt("%s:/%s", DeviceName[emuPartition], EMU_NANDS_DIR));
|
||||
NandHandle.CreatePath(fmt("%s:/%s/%s", DeviceName[emuPartition], EMU_NANDS_DIR, m_cfg.getString(WII_DOMAIN, "current_save_emunand").c_str()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_cfg.setInt(WII_DOMAIN, "savepartition", emuPartition);
|
||||
error(_t("errgame13", L"EmuNAND for gamesave not found! Using real NAND."));
|
||||
emulate_mode = 0;
|
||||
_showWaitMessage();
|
||||
}
|
||||
if(emulate_mode == 1)//gamesave
|
||||
@ -1439,10 +1463,16 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
}
|
||||
else if(emulate_mode > 1)//region switch or full
|
||||
{
|
||||
// copy real nand config files to emuNAND
|
||||
NandHandle.CreateConfig();
|
||||
// do region change on emuNAND even if region switch is not selected
|
||||
NandHandle.Do_Region_Change(id, false);
|
||||
// region change is always done because if it was changed last time then this time it may need to be set back
|
||||
// region switch is done later when D2X cIOS is detected
|
||||
}
|
||||
}
|
||||
else
|
||||
emulate_mode = 0;//sets to off we are using neek2o or launching a DVD game
|
||||
|
||||
bool use_led = m_gcfg2.getBool(id, "led", false);
|
||||
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool(WII_DOMAIN, "cheat", false));
|
||||
@ -1484,13 +1514,14 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
m_cfg.save(true);
|
||||
cleanup(); // wifi and sd gecko doesnt work anymore after cleanup
|
||||
|
||||
|
||||
//this is a temp region change of real nand(rn) for gamesave or off or DVD if tempregionrn is set true
|
||||
bool patchregion = false;
|
||||
if(emulate_mode <= 1 && !neek2o() && m_cfg.getBool("GENERAL", "tempregionrn", false))
|
||||
{
|
||||
gprintf("Check\n");
|
||||
patchregion = NandHandle.Do_Region_Change(id, true);
|
||||
}
|
||||
//load external booter bin file. if fails then wiiflow exits. would be better to show error message first.
|
||||
if(ExternalBooter_LoadBins(m_binsDir.c_str()) == false)
|
||||
Sys_Exit();
|
||||
if((!dvd || neek2o()) && !Sys_DolphinMode())
|
||||
|
@ -7,64 +7,54 @@ wstringEx gameinfo_Title_w;
|
||||
|
||||
bool titlecheck = false;
|
||||
u8 cnt_controlsreq = 0, cnt_controls = 0;
|
||||
const int pixels_to_skip = 10;
|
||||
|
||||
void CMenu::_gameinfo(void)
|
||||
{
|
||||
bool first = true;
|
||||
u8 page = 1;
|
||||
int pixels_to_skip = 10;
|
||||
int amount_of_skips = 0;
|
||||
int xtra_skips = 0;
|
||||
|
||||
SetupInput();
|
||||
_showGameInfo();
|
||||
|
||||
u8 page = 0;
|
||||
|
||||
int amount_of_skips = 0;
|
||||
|
||||
//int synopsis_x = m_theme.getInt("GAMEINFO/SYNOPSIS", "x", 40);
|
||||
int synopsis_y = m_theme.getInt("GAMEINFO/SYNOPSIS", "y", 120);
|
||||
//u16 synopsis_w = m_theme.getInt("GAMEINFO/SYNOPSIS", "width", 560);
|
||||
int synopsis_h = m_theme.getInt("GAMEINFO/SYNOPSIS", "height", 280);
|
||||
//CText text;
|
||||
u32 synopsis_th = 0;
|
||||
int dummy1 = 0;
|
||||
u32 dummy2 = 0;
|
||||
int synopsis_th = 0;
|
||||
|
||||
do
|
||||
while(!m_exit)
|
||||
{
|
||||
_mainLoopCommon();
|
||||
|
||||
if (amount_of_skips == 0 && page == 1)
|
||||
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
|
||||
break;
|
||||
if ((BTN_DOWN_PRESSED || BTN_DOWN_HELD) && !(m_thrdWorking && m_thrdStop) && page == 2 && synopsis_th > synopsis_h)
|
||||
{
|
||||
// Check dimensions in the loop, because the animation can have an effect
|
||||
m_btnMgr.getDimensions(m_gameinfoLblSynopsis, dummy1, dummy1, dummy2, synopsis_th); // Get original dimensions
|
||||
//gprintf("synopsis\nx = %i\ny = %i\nw = %i\nh = %i\n", synopsis_x, synopsis_y, synopsis_w, synopsis_h);
|
||||
}
|
||||
if (first && page == 1)
|
||||
{
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, -1);
|
||||
amount_of_skips++;
|
||||
first = false;
|
||||
}
|
||||
|
||||
if ((BTN_DOWN_PRESSED || BTN_DOWN_HELD) && !(m_thrdWorking && m_thrdStop) && page == 1)
|
||||
{
|
||||
//if (synopsis_h - (amount_of_skips * pixels_to_skip) > (m_vid.height2D() - (synopsis_y)))//+35
|
||||
if(((int)synopsis_th - 48) - (amount_of_skips * pixels_to_skip) > (synopsis_h - synopsis_y))
|
||||
if((synopsis_th - amount_of_skips * pixels_to_skip) >= synopsis_h)
|
||||
{
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, -pixels_to_skip);
|
||||
amount_of_skips++;
|
||||
}
|
||||
else if((synopsis_th - amount_of_skips * pixels_to_skip) < synopsis_h && xtra_skips == 0)
|
||||
{
|
||||
xtra_skips = pixels_to_skip - ((synopsis_th - amount_of_skips * pixels_to_skip) - synopsis_h);
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, -xtra_skips);
|
||||
}
|
||||
}
|
||||
else if ((BTN_UP_PRESSED || BTN_UP_HELD) && !(m_thrdWorking && m_thrdStop) && page == 1)
|
||||
else if ((BTN_UP_PRESSED || BTN_UP_HELD) && !(m_thrdWorking && m_thrdStop) && page == 2)
|
||||
{
|
||||
if (amount_of_skips > 1)
|
||||
if(xtra_skips > 0)
|
||||
{
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, xtra_skips);
|
||||
xtra_skips = 0;
|
||||
}
|
||||
else if (amount_of_skips > 0)
|
||||
{
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, pixels_to_skip);
|
||||
amount_of_skips--;
|
||||
}
|
||||
}
|
||||
else if (BTN_RIGHT_PRESSED && !(m_thrdWorking && m_thrdStop) && page == 0 && !gameinfo_Synopsis_w.empty())
|
||||
else if (BTN_RIGHT_PRESSED && !(m_thrdWorking && m_thrdStop) && page == 1 && !gameinfo_Synopsis_w.empty())
|
||||
{
|
||||
page = 1;
|
||||
page = 2;
|
||||
amount_of_skips = 0;
|
||||
|
||||
m_btnMgr.hide(m_gameinfoLblID, true);
|
||||
@ -93,11 +83,12 @@ void CMenu::_gameinfo(void)
|
||||
|
||||
m_btnMgr.reset(m_gameinfoLblSynopsis);
|
||||
m_btnMgr.show(m_gameinfoLblSynopsis, false);
|
||||
m_btnMgr.getTotalHeight(m_gameinfoLblSynopsis, synopsis_th);
|
||||
m_btnMgr.moveBy(m_gameinfoLblSynopsis, 0, -1);
|
||||
}
|
||||
else if (BTN_LEFT_PRESSED && !(m_thrdWorking && m_thrdStop))
|
||||
{
|
||||
page = 0;
|
||||
first = true;
|
||||
page = 1;
|
||||
m_btnMgr.show(m_gameinfoLblID);
|
||||
m_btnMgr.show(m_gameinfoLblDev);
|
||||
m_btnMgr.show(m_gameinfoLblRegion);
|
||||
@ -124,9 +115,7 @@ void CMenu::_gameinfo(void)
|
||||
|
||||
m_btnMgr.hide(m_gameinfoLblSynopsis,true);
|
||||
}
|
||||
|
||||
} while (!BTN_HOME_PRESSED && !BTN_B_PRESSED);
|
||||
|
||||
}
|
||||
_hideGameInfo(false);
|
||||
}
|
||||
|
||||
|
@ -25,13 +25,13 @@ s16 m_exittoLblUser[4];
|
||||
|
||||
s16 m_homeBtnSettings;
|
||||
s16 m_homeBtnReloadCache;
|
||||
s16 m_homeBtnUpdate;
|
||||
//s16 m_homeBtnUpdate;
|
||||
s16 m_homeBtnExplorer;
|
||||
|
||||
s16 m_homeBtnInstall;
|
||||
s16 m_homeBtnAbout;
|
||||
s16 m_homeBtnExitTo;
|
||||
s16 m_homeBtnFTP;
|
||||
s16 m_homeBtnSelPlugin;
|
||||
|
||||
s16 m_homeBtnExitToHBC;
|
||||
s16 m_homeBtnExitToMenu;
|
||||
@ -71,7 +71,7 @@ bool CMenu::_Home(void)
|
||||
m_load_view = true;
|
||||
break;
|
||||
}
|
||||
else if(m_btnMgr.selected(m_homeBtnUpdate) && !m_locked)
|
||||
/*else if(m_btnMgr.selected(m_homeBtnUpdate) && !m_locked)
|
||||
{
|
||||
CoverFlow.stopCoverLoader(true);
|
||||
_hideHome();
|
||||
@ -84,7 +84,7 @@ bool CMenu::_Home(void)
|
||||
_showHome();
|
||||
CoverFlow.startCoverLoader();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
else if(m_btnMgr.selected(m_homeBtnInstall))
|
||||
{
|
||||
_hideHome();
|
||||
@ -112,10 +112,12 @@ bool CMenu::_Home(void)
|
||||
_Explorer();
|
||||
_showHome();
|
||||
}
|
||||
else if(m_btnMgr.selected(m_homeBtnFTP))
|
||||
else if(m_btnMgr.selected(m_homeBtnSelPlugin))
|
||||
{
|
||||
_hideHome();
|
||||
_FTP();
|
||||
_PluginSettings();
|
||||
if(m_load_view)
|
||||
break;
|
||||
_showHome();
|
||||
}
|
||||
}
|
||||
@ -199,13 +201,13 @@ void CMenu::_showHome(void)
|
||||
|
||||
m_btnMgr.show(m_homeBtnSettings);
|
||||
m_btnMgr.show(m_homeBtnReloadCache);
|
||||
m_btnMgr.show(m_homeBtnUpdate);
|
||||
//m_btnMgr.show(m_homeBtnUpdate);
|
||||
m_btnMgr.show(m_homeBtnExplorer);
|
||||
|
||||
m_btnMgr.show(m_homeBtnInstall);
|
||||
m_btnMgr.show(m_homeBtnAbout);
|
||||
m_btnMgr.show(m_homeBtnExitTo);
|
||||
m_btnMgr.show(m_homeBtnFTP);
|
||||
m_btnMgr.show(m_homeBtnSelPlugin);
|
||||
|
||||
m_btnMgr.show(m_homeLblBattery);
|
||||
|
||||
@ -236,13 +238,13 @@ void CMenu::_hideHome(bool instant)
|
||||
|
||||
m_btnMgr.hide(m_homeBtnSettings, instant);
|
||||
m_btnMgr.hide(m_homeBtnReloadCache, instant);
|
||||
m_btnMgr.hide(m_homeBtnUpdate, instant);
|
||||
//m_btnMgr.hide(m_homeBtnUpdate, instant);
|
||||
m_btnMgr.hide(m_homeBtnExplorer, instant);
|
||||
|
||||
m_btnMgr.hide(m_homeBtnInstall, instant);
|
||||
m_btnMgr.hide(m_homeBtnAbout, instant);
|
||||
m_btnMgr.hide(m_homeBtnExitTo, instant);
|
||||
m_btnMgr.hide(m_homeBtnFTP, instant);
|
||||
m_btnMgr.hide(m_homeBtnSelPlugin, instant);
|
||||
|
||||
m_btnMgr.hide(m_homeLblBattery, instant);
|
||||
|
||||
@ -278,25 +280,25 @@ void CMenu::_initHomeAndExitToMenu()
|
||||
|
||||
m_homeBtnSettings = _addButton("HOME/SETTINGS", theme.btnFont, L"", 60, 100, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnReloadCache = _addButton("HOME/RELOAD_CACHE", theme.btnFont, L"", 60, 180, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnUpdate = _addButton("HOME/UPDATE", theme.btnFont, L"", 60, 260, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnExplorer = _addButton("HOME/EXPLORER", theme.btnFont, L"", 60, 340, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnExplorer = _addButton("HOME/EXPLORER", theme.btnFont, L"", 60, 260, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnSelPlugin = _addButton("HOME/FTP", theme.btnFont, L"", 60, 340, 250, 48, theme.btnFontColor);
|
||||
|
||||
m_homeBtnInstall = _addButton("HOME/INSTALL", theme.btnFont, L"", 330, 100, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnAbout = _addButton("HOME/ABOUT", theme.btnFont, L"", 330, 180, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnAbout = _addButton("HOME/ABOUT", theme.btnFont, L"", 330, 100, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnInstall = _addButton("HOME/INSTALL", theme.btnFont, L"", 330, 180, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnExitTo = _addButton("HOME/EXIT_TO", theme.btnFont, L"", 330, 260, 250, 48, theme.btnFontColor);
|
||||
m_homeBtnFTP = _addButton("HOME/FTP", theme.btnFont, L"", 330, 340, 250, 48, theme.btnFontColor);
|
||||
//m_homeBtnUpdate = _addButton("HOME/UPDATE", theme.btnFont, L"", 330, 340, 250, 48, theme.btnFontColor);
|
||||
|
||||
m_homeLblBattery = _addLabel("HOME/BATTERY", theme.btnFont, L"", 0, 420, 640, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
|
||||
_setHideAnim(m_homeBtnSettings, "HOME/SETTINGS", 50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnReloadCache, "HOME/RELOAD_CACHE", 50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnUpdate, "HOME/UPDATE", 50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnSelPlugin, "HOME/FTP", 50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnExplorer, "HOME/EXPLORER", 50, 0, 1.f, 0.f);
|
||||
|
||||
_setHideAnim(m_homeBtnInstall, "HOME/INSTALL", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnAbout, "HOME/ABOUT", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnExitTo, "HOME/EXIT_TO", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_homeBtnFTP, "HOME/FTP", -50, 0, 1.f, 0.f);
|
||||
//_setHideAnim(m_homeBtnUpdate, "HOME/UPDATE", -50, 0, 1.f, 0.f);
|
||||
|
||||
_setHideAnim(m_homeLblBattery, "HOME/BATTERY", 0, 0, -2.f, 0.f);
|
||||
|
||||
@ -329,13 +331,13 @@ void CMenu::_textHome(void)
|
||||
m_btnMgr.setText(m_homeLblTitle, VERSION_STRING);
|
||||
m_btnMgr.setText(m_homeBtnSettings, _t("about10", L"Help Guide"));
|
||||
m_btnMgr.setText(m_homeBtnReloadCache, _t("home2", L"Reload Cache"));
|
||||
m_btnMgr.setText(m_homeBtnUpdate, _t("home3", L"Update"));
|
||||
//m_btnMgr.setText(m_homeBtnUpdate, _t("home3", L"Update"));
|
||||
m_btnMgr.setText(m_homeBtnExplorer, _t("home8", L"File Explorer"));
|
||||
|
||||
m_btnMgr.setText(m_homeBtnInstall, _t("home7", L"Install Game"));
|
||||
m_btnMgr.setText(m_homeBtnAbout, _t("home4", L"Credits"));
|
||||
m_btnMgr.setText(m_homeBtnExitTo, _t("home5", L"Exit To"));
|
||||
m_btnMgr.setText(m_homeBtnFTP, _t("home10", L"FTP Server"));
|
||||
m_btnMgr.setText(m_homeBtnSelPlugin, _t("cfgpl1", L"Select Plugins"));
|
||||
}
|
||||
|
||||
void CMenu::_textExitTo(void)
|
||||
|
@ -46,7 +46,6 @@ void CMenu::_hideMain(bool instant)
|
||||
|
||||
void CMenu::_showMain(void)
|
||||
{
|
||||
start_main:
|
||||
_hideWaitMessage();
|
||||
#ifdef SHOWMEM
|
||||
m_btnMgr.show(m_mem1FreeSize);
|
||||
@ -55,9 +54,9 @@ start_main:
|
||||
m_vid.set2DViewport(m_cfg.getInt("GENERAL", "tv_width", 640), m_cfg.getInt("GENERAL", "tv_height", 480),
|
||||
m_cfg.getInt("GENERAL", "tv_x", 0), m_cfg.getInt("GENERAL", "tv_y", 0));
|
||||
_setBg(m_mainBg, m_mainBgLQ);
|
||||
m_btnMgr.show(m_mainBtnInfo);
|
||||
//m_btnMgr.show(m_mainBtnInfo);
|
||||
m_btnMgr.show(m_mainBtnConfig);
|
||||
m_btnMgr.show(m_mainBtnQuit);
|
||||
m_btnMgr.show(m_mainBtnQuit);// home btn
|
||||
|
||||
switch(m_current_view)
|
||||
{
|
||||
@ -96,42 +95,40 @@ start_main:
|
||||
if(m_mainLblUser[i] != -1)
|
||||
m_btnMgr.show(m_mainLblUser[i]);
|
||||
|
||||
wstringEx Msg;
|
||||
wstringEx Pth;
|
||||
if(m_gameList.empty())
|
||||
{
|
||||
switch(m_current_view)
|
||||
{
|
||||
case COVERFLOW_WII:
|
||||
Msg = _t("main2", L"No games found in ");
|
||||
Pth = wstringEx(fmt(wii_games_dir, DeviceName[currentPartition]));
|
||||
break;
|
||||
case COVERFLOW_GAMECUBE:
|
||||
m_btnMgr.setText(m_mainLblMessage, _t("main2", L"No games found! Please select partition to change the device/partition or click Install to install a game."));
|
||||
m_btnMgr.show(m_mainBtnInstall);
|
||||
m_btnMgr.show(m_mainBtnSelPart);
|
||||
m_btnMgr.show(m_mainLblMessage);
|
||||
Msg = _t("main2", L"No games found in ");
|
||||
Pth = wstringEx(fmt(gc_games_dir, DeviceName[currentPartition]));
|
||||
break;
|
||||
case COVERFLOW_CHANNEL:
|
||||
if(NANDemuView)
|
||||
{
|
||||
_hideMain();
|
||||
if(!_AutoCreateNand())
|
||||
{
|
||||
// if emu nand disabled set to real nand only
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", false);
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", true);
|
||||
}
|
||||
_loadList();
|
||||
goto start_main;
|
||||
}
|
||||
Msg = _t("main3", L"No titles found in ");
|
||||
Pth = wstringEx(fmt("%s:/%s/%s", DeviceName[currentPartition], EMU_NANDS_DIR, m_cfg.getString(CHANNEL_DOMAIN, "current_emunand").c_str()));
|
||||
break;
|
||||
case COVERFLOW_HOMEBREW:
|
||||
m_btnMgr.setText(m_mainLblMessage, _t("main4", L"No homebrew apps found! Try changing the partition to select the correct device/partition."));
|
||||
m_btnMgr.show(m_mainBtnSelPart);
|
||||
m_btnMgr.show(m_mainLblMessage);
|
||||
Msg = _t("main4", L"No apps found in ");
|
||||
Pth = wstringEx(fmt(HOMEBREW_DIR, DeviceName[currentPartition]));
|
||||
break;
|
||||
case COVERFLOW_PLUGIN:
|
||||
m_btnMgr.setText(m_mainLblMessage, _t("main5", L"No roms/items for your plugin found! Try changing the partition to select the correct device/partition."));
|
||||
m_btnMgr.show(m_mainBtnSelPart);
|
||||
m_btnMgr.show(m_mainLblMessage);
|
||||
m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(enabledPluginsCount == 0)
|
||||
Msg = _t("main6", L"No plugins selected.");
|
||||
else
|
||||
Msg = _t("main5", L"No roms/items found.");
|
||||
Pth = "";
|
||||
break;
|
||||
}
|
||||
Msg.append(Pth);
|
||||
m_btnMgr.setText(m_mainLblMessage, Msg);
|
||||
m_btnMgr.show(m_mainLblMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +136,7 @@ void CMenu::LoadView(void)
|
||||
{
|
||||
m_load_view = false;
|
||||
_hideMain(true);
|
||||
CoverFlow.clear();
|
||||
|
||||
if(!m_vid.showingWaitMessage())
|
||||
_showWaitMessage();
|
||||
|
||||
@ -161,21 +158,15 @@ void CMenu::LoadView(void)
|
||||
cf_domain = "_SMALLFLOW";
|
||||
if(m_current_view == COVERFLOW_PLUGIN && !m_sourceflow)
|
||||
{
|
||||
vector<bool> pluginsEnabled = m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(pluginsEnabled.size() > 0)
|
||||
m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(enabledPluginsCount > 0)
|
||||
{
|
||||
int sdc = 0;
|
||||
int shc = 0;
|
||||
for(u8 i = 0; i < pluginsEnabled.size(); ++i)
|
||||
for(u8 i = 0; m_plugin.PluginExist(i); ++i)
|
||||
{
|
||||
if(pluginsEnabled[i] == true)
|
||||
if(m_plugin.GetEnableStatus(m_cfg, m_plugin.getPluginMagic(i)))
|
||||
{
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", m_plugin.getPluginMagic(i)), 8);
|
||||
if(enabledPluginsCount == 1)
|
||||
{
|
||||
currentPartition = m_cfg.getInt("PLUGINS_PARTITION", m_plugin.PluginMagicWord, 1);
|
||||
m_cfg.setInt(PLUGIN_DOMAIN, "partition", currentPartition);
|
||||
}
|
||||
if(_sideCover(m_plugin.PluginMagicWord))
|
||||
sdc++;
|
||||
else if(_shortCover(m_plugin.PluginMagicWord))
|
||||
@ -237,25 +228,8 @@ void CMenu::LoadView(void)
|
||||
if(m_sourceflow || m_current_view == COVERFLOW_HOMEBREW)
|
||||
return;
|
||||
|
||||
m_showtimer = 120;
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
{
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "real_nand"))
|
||||
{
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand"))
|
||||
m_btnMgr.setText(m_mainLblNotice, sfmt("Total Channels: %u", m_gameList.size()));
|
||||
else
|
||||
m_btnMgr.setText(m_mainLblNotice, sfmt("NAND Channels: %u", m_gameList.size()));
|
||||
}
|
||||
else
|
||||
m_btnMgr.setText(m_mainLblNotice, sfmt("EmuNand Channels: %u", m_gameList.size()));
|
||||
}
|
||||
else if(m_current_view == COVERFLOW_MAX || m_current_view == COVERFLOW_PLUGIN)
|
||||
{
|
||||
m_btnMgr.setText(m_mainLblNotice, sfmt("Total Games: %u", m_gameList.size()));
|
||||
}
|
||||
else
|
||||
m_btnMgr.setText(m_mainLblNotice, sfmt("%s Games: %u", _domainFromView(), m_gameList.size()));
|
||||
m_showtimer = 240;
|
||||
m_btnMgr.setText(m_mainLblNotice, wfmt(_fmt("main7", L"Total Games: %u"), CoverFlow.size()));
|
||||
m_btnMgr.show(m_mainLblNotice);
|
||||
}
|
||||
|
||||
@ -277,12 +251,10 @@ void CMenu::exitHandler(int ExitTo)
|
||||
int CMenu::main(void)
|
||||
{
|
||||
wstringEx curLetter;
|
||||
string prevTheme = m_cfg.getString("GENERAL", "theme", "default");
|
||||
parental_homebrew = m_cfg.getBool(HOMEBREW_DOMAIN, "parental", false);
|
||||
show_homebrew = (!m_cfg.getBool(HOMEBREW_DOMAIN, "disable", false) && (parental_homebrew || !m_locked));
|
||||
const char *prevTheme = m_cfg.getString("GENERAL", "theme", "default").c_str();
|
||||
show_channel = !m_cfg.getBool(CHANNEL_DOMAIN, "disable", false);
|
||||
show_plugin = !m_cfg.getBool(PLUGIN_DOMAIN, "disable", false);
|
||||
show_gamecube = m_show_gc;
|
||||
show_gamecube = !m_cfg.getBool(GC_DOMAIN, "disable", false);
|
||||
m_allow_random = m_cfg.getBool("GENERAL", "allow_b_on_questionmark", true);
|
||||
m_multisource = m_cfg.getBool("GENERAL", "multisource", false);
|
||||
bool m_source_on_start = m_cfg.getBool("GENERAL", "source_on_start", false);
|
||||
@ -293,30 +265,49 @@ int CMenu::main(void)
|
||||
u32 disc_check = 0;
|
||||
|
||||
SetupInput(true);
|
||||
GameTDB m_gametdb;
|
||||
m_gametdb.OpenFile(fmt("%s/wiitdb.xml", m_settingsDir.c_str()));
|
||||
m_GameTDBAvailable = false;
|
||||
if(m_gametdb.IsLoaded())
|
||||
|
||||
u8 sourceCount = 0;
|
||||
if(m_cfg.getBool(WII_DOMAIN, "source", false))
|
||||
{
|
||||
m_GameTDBAvailable = true;
|
||||
m_gametdb.CloseFile();
|
||||
sourceCount++;
|
||||
m_current_view = COVERFLOW_WII;
|
||||
}
|
||||
m_current_view = max(m_cfg.getInt("GENERAL", "last_view", 0), 0);
|
||||
if(m_current_view > COVERFLOW_MAX || m_current_view == COVERFLOW_HOMEBREW)
|
||||
if(m_cfg.getBool(GC_DOMAIN, "source", false))
|
||||
{
|
||||
sourceCount++;
|
||||
m_current_view = COVERFLOW_GAMECUBE;
|
||||
}
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "source", false))
|
||||
{
|
||||
sourceCount++;
|
||||
m_current_view = COVERFLOW_CHANNEL;
|
||||
}
|
||||
if(m_cfg.getBool(HOMEBREW_DOMAIN, "source", false))
|
||||
{
|
||||
sourceCount++;
|
||||
m_current_view = COVERFLOW_HOMEBREW;
|
||||
}
|
||||
if(m_cfg.getBool(PLUGIN_DOMAIN, "source", false))
|
||||
{
|
||||
sourceCount++;
|
||||
m_current_view = COVERFLOW_PLUGIN;
|
||||
}
|
||||
if(sourceCount > 1)
|
||||
{
|
||||
m_combined_view = true;
|
||||
m_current_view = COVERFLOW_MAX;
|
||||
}
|
||||
if(sourceCount == 0 || m_current_view == COVERFLOW_HOMEBREW)
|
||||
{
|
||||
m_current_view = COVERFLOW_WII;
|
||||
_clearSources();
|
||||
m_cfg.setBool(HOMEBREW_DOMAIN, "source", false);
|
||||
m_cfg.setBool(WII_DOMAIN, "source", true);
|
||||
}
|
||||
|
||||
m_catStartPage = m_cfg.getInt("GENERAL", "cat_startpage", 1);
|
||||
if(m_current_view != COVERFLOW_MAX)
|
||||
{
|
||||
m_cfg.remove("GENERAL", "last_view");
|
||||
m_cfg.remove("GENERAL", "cat_startpage");
|
||||
}
|
||||
else
|
||||
m_combined_view = true;
|
||||
//m_cfg.save();
|
||||
|
||||
if(m_cfg.getBool("GENERAL", "update_cache", false))
|
||||
UpdateCache();
|
||||
LoadView();
|
||||
@ -409,10 +400,10 @@ int CMenu::main(void)
|
||||
CoverFlow.pageUp();
|
||||
else if(m_btnMgr.selected(m_mainBtnNext))
|
||||
CoverFlow.pageDown();
|
||||
else if(m_btnMgr.selected(m_mainBtnQuit))
|
||||
else if(m_btnMgr.selected(m_mainBtnQuit))//home button
|
||||
{
|
||||
_hideMain();
|
||||
if(_Home()) //exit wiiflow
|
||||
if(_Home()) //home menu
|
||||
break;
|
||||
if(BTN_B_HELD)
|
||||
bUsed = true;
|
||||
@ -423,14 +414,13 @@ int CMenu::main(void)
|
||||
}
|
||||
else if(m_btnMgr.selected(m_mainBtnChannel) || m_btnMgr.selected(m_mainBtnWii) || m_btnMgr.selected(m_mainBtnGamecube) || m_btnMgr.selected(m_mainBtnPlugin))
|
||||
{
|
||||
if(m_multisource) continue;
|
||||
if(m_current_view == COVERFLOW_WII)
|
||||
m_current_view = show_gamecube ? COVERFLOW_GAMECUBE : (show_channel ? COVERFLOW_CHANNEL : (show_plugin ? COVERFLOW_PLUGIN : COVERFLOW_WII));
|
||||
else if(m_current_view == COVERFLOW_GAMECUBE)
|
||||
m_current_view = show_channel ? COVERFLOW_CHANNEL : (show_plugin ? COVERFLOW_PLUGIN : COVERFLOW_WII);
|
||||
else if(m_current_view == COVERFLOW_CHANNEL)
|
||||
m_current_view = show_plugin ? COVERFLOW_PLUGIN : COVERFLOW_WII;
|
||||
else if(m_current_view == COVERFLOW_PLUGIN)
|
||||
else if(m_current_view == COVERFLOW_PLUGIN || m_current_view == COVERFLOW_MAX)
|
||||
m_current_view = COVERFLOW_WII;
|
||||
_clearSources();
|
||||
m_cfg.setBool(_domainFromView(), "source", true);
|
||||
@ -441,49 +431,23 @@ int CMenu::main(void)
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", true);
|
||||
LoadView();
|
||||
}
|
||||
else if(m_btnMgr.selected(m_mainBtnInstall))//used when no games found
|
||||
{
|
||||
if(!m_locked)
|
||||
{
|
||||
_hideMain();
|
||||
_wbfsOp(CMenu::WO_ADD_GAME);
|
||||
_showMain();
|
||||
if(BTN_B_HELD)
|
||||
bUsed = true;
|
||||
}
|
||||
}
|
||||
else if(m_btnMgr.selected(m_mainBtnSelPart))//used when no games found
|
||||
{
|
||||
_hideMain();
|
||||
_config(1);
|
||||
if(prevTheme != m_cfg.getString("GENERAL", "theme"))
|
||||
{
|
||||
m_reload = true;
|
||||
break;
|
||||
}
|
||||
_showMain();
|
||||
if(BTN_B_HELD)
|
||||
bUsed = true;
|
||||
}
|
||||
else if(m_btnMgr.selected(m_mainBtnConfig))
|
||||
{
|
||||
_hideMain();
|
||||
_config(1);
|
||||
if(prevTheme != m_cfg.getString("GENERAL", "theme"))
|
||||
if(strcmp(prevTheme, m_cfg.getString("GENERAL", "theme").c_str()) != 0)
|
||||
{
|
||||
m_reload = true;
|
||||
break;
|
||||
}
|
||||
if(BTN_B_HELD)
|
||||
bUsed = true;
|
||||
//update show_homebrew because parental lock might have changed
|
||||
show_homebrew = (!m_cfg.getBool(HOMEBREW_DOMAIN, "disable", false) && (parental_homebrew || !m_locked));
|
||||
if(m_load_view)
|
||||
LoadView();
|
||||
else
|
||||
_showMain();
|
||||
}
|
||||
else if(m_btnMgr.selected(m_mainBtnHomebrew))
|
||||
else if(m_btnMgr.selected(m_mainBtnHomebrew) && (!m_locked || !m_cfg.getBool(HOMEBREW_DOMAIN, "parental", false)))
|
||||
{
|
||||
m_prev_view = m_current_view;
|
||||
m_current_view = COVERFLOW_HOMEBREW;
|
||||
@ -689,7 +653,7 @@ int CMenu::main(void)
|
||||
bUsed = true;
|
||||
MusicPlayer.Next();
|
||||
}
|
||||
else if(BTN_PLUS_PRESSED && !m_locked && !m_sourceflow)
|
||||
else if(BTN_PLUS_PRESSED && !m_locked && !m_sourceflow && m_current_view < 3)
|
||||
{
|
||||
bUsed = true;
|
||||
u32 sort = 0;
|
||||
@ -715,14 +679,6 @@ int CMenu::main(void)
|
||||
m_btnMgr.setText(m_mainLblNotice, curSort);
|
||||
m_btnMgr.show(m_mainLblNotice);
|
||||
}
|
||||
else if(BTN_MINUS_PRESSED && !m_locked && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
{
|
||||
bUsed = true;
|
||||
_showWaitMessage();
|
||||
_hideMain();
|
||||
_setPartition(1);
|
||||
LoadView();
|
||||
}
|
||||
}
|
||||
/* Hide Notice or Letter if times up */
|
||||
if(m_showtimer > 0)
|
||||
@ -742,7 +698,7 @@ int CMenu::main(void)
|
||||
m_btnMgr.show(m_mainBtnNext);
|
||||
else
|
||||
m_btnMgr.hide(m_mainBtnNext);
|
||||
if(!m_gameList.empty() && m_show_zone_main && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
if(m_show_zone_main && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
{
|
||||
m_btnMgr.show(m_mainLblUser[0]);
|
||||
m_btnMgr.show(m_mainLblUser[1]);
|
||||
@ -764,7 +720,7 @@ int CMenu::main(void)
|
||||
m_btnMgr.hide(m_mainBtnFavoritesOn);
|
||||
m_btnMgr.hide(m_mainBtnFavoritesOff);
|
||||
}
|
||||
if((!m_cfg.getBool("GENERAL", "hideviews", false) && (m_gameList.empty() || m_show_zone_main2)) && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
if(!m_cfg.getBool("GENERAL", "hideviews", false) && m_show_zone_main2 && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
{
|
||||
switch(m_current_view)
|
||||
{
|
||||
@ -810,7 +766,7 @@ int CMenu::main(void)
|
||||
m_btnMgr.hide(m_mainLblUser[2]);
|
||||
m_btnMgr.hide(m_mainLblUser[3]);
|
||||
}
|
||||
if(((disc_check & 0x2) && (m_gameList.empty() || m_show_zone_main3)) && !m_sourceflow)
|
||||
if((disc_check & 0x2) && m_show_zone_main3 && !m_sourceflow && m_current_view != COVERFLOW_HOMEBREW)
|
||||
{
|
||||
m_btnMgr.show(m_mainBtnDVD);
|
||||
m_btnMgr.show(m_mainLblUser[4]);
|
||||
@ -851,9 +807,12 @@ int CMenu::main(void)
|
||||
Sys_SetNeekPath(ReturnPath);
|
||||
}
|
||||
//gprintf("Saving configuration files\n");
|
||||
m_cfg.save();
|
||||
m_cat.save();
|
||||
// m_loc.save();
|
||||
m_gcfg1.save(true);// save configs
|
||||
m_gcfg2.save(true);
|
||||
m_cat.save(true);
|
||||
m_cfg.save(true);
|
||||
//m_cfg.save();
|
||||
//m_cat.save();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1100,13 +1059,13 @@ wstringEx CMenu::_getNoticeTranslation(int sorting, wstringEx curLetter)
|
||||
|
||||
void CMenu::_setPartition(s8 direction)
|
||||
{
|
||||
if(m_current_view == COVERFLOW_CHANNEL && neek2o())
|
||||
if((m_current_view == COVERFLOW_CHANNEL && neek2o()) || m_current_view == COVERFLOW_MAX)
|
||||
return;
|
||||
int FS_Type = 0;
|
||||
/* change partition if direction is not zero */
|
||||
if(direction != 0)
|
||||
{
|
||||
bool NeedFAT = m_current_view == COVERFLOW_CHANNEL || m_current_view == COVERFLOW_GAMECUBE;
|
||||
bool NeedFAT = m_current_view == COVERFLOW_CHANNEL || m_current_view == COVERFLOW_GAMECUBE || m_emuSaveNand == true;
|
||||
u8 limiter = 0;
|
||||
do
|
||||
{
|
||||
@ -1121,25 +1080,7 @@ void CMenu::_setPartition(s8 direction)
|
||||
/* set partition to currentPartition */
|
||||
if(m_emuSaveNand)
|
||||
m_cfg.setInt(WII_DOMAIN, "savepartition", currentPartition);
|
||||
else
|
||||
{
|
||||
if(direction == 0 || (direction != 0 && (m_current_view != COVERFLOW_CHANNEL ||
|
||||
else if(direction == 0 || (direction != 0 && (m_current_view != COVERFLOW_CHANNEL ||
|
||||
(FS_Type != -1 && DeviceHandle.IsInserted(currentPartition)))))
|
||||
m_cfg.setInt(_domainFromView(), "partition", currentPartition);
|
||||
if(m_current_view == COVERFLOW_PLUGIN)
|
||||
{
|
||||
vector<bool> plugin_list = m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(enabledPluginsCount == 1)
|
||||
{
|
||||
u8 i = 0;
|
||||
for(i = 0; i < plugin_list.size(); ++i)
|
||||
{
|
||||
if(plugin_list[i] == true)
|
||||
break;
|
||||
}
|
||||
strncpy(m_plugin.PluginMagicWord, fmt("%08x", m_plugin.getPluginMagic(i)), 8);
|
||||
m_cfg.setInt("PLUGINS_PARTITION", m_plugin.PluginMagicWord, currentPartition);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cfg.setInt(_domainFromView(), "partition", currentPartition);
|
||||
}
|
||||
|
@ -14,19 +14,34 @@ s16 m_nandemuBtnBack;
|
||||
s16 m_nandemuLblPage;
|
||||
s16 m_nandemuBtnPageM;
|
||||
s16 m_nandemuBtnPageP;
|
||||
s16 m_nandemuLblEmulationVal;
|
||||
|
||||
s16 m_nandemuLblNandSelect;
|
||||
s16 m_nandemuLblNandSelectVal;
|
||||
s16 m_nandemuBtnNandSelectM;
|
||||
s16 m_nandemuBtnNandSelectP;
|
||||
s16 m_nandemuLblEmulation;
|
||||
s16 m_nandemuLblEmulationVal;
|
||||
s16 m_nandemuBtnEmulationM;
|
||||
s16 m_nandemuBtnEmulationP;
|
||||
s16 m_nandemuLblSaveNandSelect;
|
||||
s16 m_nandemuLblSaveNandSelectVal;
|
||||
s16 m_nandemuBtnSaveNandSelectM;
|
||||
s16 m_nandemuBtnSaveNandSelectP;
|
||||
s16 m_nandemuLblSaveEmulation;
|
||||
s16 m_nandemuLblSaveEmulationVal;
|
||||
s16 m_nandemuBtnSaveEmulationM;
|
||||
s16 m_nandemuBtnSaveEmulationP;
|
||||
|
||||
s16 m_nandemuLblSaveDump;
|
||||
s16 m_nandemuBtnAll;
|
||||
s16 m_nandemuBtnMissing;
|
||||
s16 m_nandemuLblNandDump;
|
||||
s16 m_nandemuBtnNandDump;
|
||||
s16 m_nandemuLblNandSelect;
|
||||
s16 m_nandemuLblNandSelectVal;
|
||||
s16 m_nandemuBtnNandSelectM;
|
||||
s16 m_nandemuBtnNandSelectP;
|
||||
s16 m_nandemuLblSavePartition;
|
||||
s16 m_nandemuLblSavePartitionVal;
|
||||
s16 m_nandemuBtnSavePartitionM;
|
||||
s16 m_nandemuBtnSavePartitionP;
|
||||
|
||||
s16 m_nandfileLblMessage;
|
||||
s16 m_nandemuLblMessage;
|
||||
s16 m_nandfileLblDialog;
|
||||
@ -138,7 +153,7 @@ int CMenu::_FindEmuPart(string &emuPath, bool skipchecks, bool savesnand)
|
||||
}
|
||||
if(!DeviceHandle.PartitionUsableForNandEmu(emuPart))
|
||||
return -1;
|
||||
else if((skipchecks || _TestEmuNand(emuPart, tmpPath, true)))
|
||||
else if((skipchecks || _TestEmuNand(emuPart, tmpPath, true)))// true should only be true if emulation set to full
|
||||
{
|
||||
NandHandle.SetNANDEmu(emuPart);
|
||||
NandHandle.SetPaths(tmpPath, DeviceName[emuPart]);
|
||||
@ -202,12 +217,12 @@ bool CMenu::_checkSave(string id, bool nand)
|
||||
else
|
||||
{
|
||||
int emuPartition = m_cfg.getInt(WII_DOMAIN, "savepartition", m_cfg.getInt(CHANNEL_DOMAIN, "partition", 0));
|
||||
string emuPath = m_cfg.getString(WII_DOMAIN, "savepath", "");
|
||||
if(emuPartition < 0 || emuPath.size() == 0)
|
||||
const char *emuPath = fmt("/%s/%s", EMU_NANDS_DIR, m_cfg.getString(WII_DOMAIN, "current_save_emunand", m_cfg.getString(CHANNEL_DOMAIN, "current_emunand", "default")).c_str());
|
||||
if(emuPartition < 0 || emuPath == NULL)
|
||||
return false;
|
||||
struct stat fstat;
|
||||
if((stat(fmt("%s:%s/title/00010000/%08x", DeviceName[emuPartition], emuPath.c_str(), savePath), &fstat) != 0 )
|
||||
&& (stat(fmt("%s:%s/title/00010004/%08x", DeviceName[emuPartition], emuPath.c_str(), savePath), &fstat) != 0))
|
||||
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))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -246,6 +261,7 @@ void CMenu::_hideNandEmu(bool instant)
|
||||
m_btnMgr.hide(m_nandemuLblPage, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnPageM, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnPageP, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandfilePBar, instant);
|
||||
m_btnMgr.hide(m_nandemuPBar, instant);
|
||||
m_btnMgr.hide(m_nandfileLblMessage, instant);
|
||||
@ -253,23 +269,42 @@ void CMenu::_hideNandEmu(bool instant)
|
||||
m_btnMgr.hide(m_nandfileLblDialog, instant);
|
||||
m_btnMgr.hide(m_nandemuLblDialog, instant);
|
||||
m_btnMgr.hide(m_nandfinLblDialog, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, instant);
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSavePartition, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSavePartitionVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuBtnExtract, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnPartition, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnDisable, instant);
|
||||
m_btnMgr.hide(m_nandemuLblInit, instant);
|
||||
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_nandemuLblUser); ++i)
|
||||
if(m_nandemuLblUser[i] != -1)
|
||||
m_btnMgr.hide(m_nandemuLblUser[i], instant);
|
||||
@ -289,41 +324,51 @@ void CMenu::_showNandEmu(void)
|
||||
|
||||
if(nandemuPage == 1)
|
||||
{
|
||||
int i;
|
||||
if(((m_current_view == COVERFLOW_CHANNEL && m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand", false)) || m_current_view == COVERFLOW_WII))
|
||||
{
|
||||
m_btnMgr.show(m_nandemuLblEmulation);
|
||||
m_btnMgr.show(m_nandemuLblEmulationVal);
|
||||
m_btnMgr.show(m_nandemuBtnEmulationP);
|
||||
m_btnMgr.show(m_nandemuBtnEmulationM);
|
||||
}
|
||||
|
||||
m_btnMgr.show(m_nandemuLblSaveDump);
|
||||
m_btnMgr.show(m_nandemuBtnAll);
|
||||
m_btnMgr.show(m_nandemuBtnMissing);
|
||||
m_btnMgr.show(m_nandemuLblNandDump);
|
||||
m_btnMgr.show(m_nandemuBtnNandDump);
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
{
|
||||
i = min(max(0, m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0)), (int)ARRAY_SIZE(CMenu::_NandEmu) - 1);
|
||||
m_btnMgr.setText(m_nandemuLblEmulationVal, _t(CMenu::_NandEmu[i].id, CMenu::_NandEmu[i].text));
|
||||
}
|
||||
else if(m_current_view == COVERFLOW_WII)
|
||||
{
|
||||
i = min(max(0, m_cfg.getInt(WII_DOMAIN, "save_emulation", 0)), (int)ARRAY_SIZE(CMenu::_GlobalSaveEmu) - 1);
|
||||
m_btnMgr.setText(m_nandemuLblEmulationVal, _t(CMenu::_GlobalSaveEmu[i].id, CMenu::_GlobalSaveEmu[i].text));
|
||||
}
|
||||
}
|
||||
else //page 2
|
||||
{
|
||||
int i = min(max(0, m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0)), (int)ARRAY_SIZE(CMenu::_NandEmu) - 1);
|
||||
m_btnMgr.setText(m_nandemuLblEmulationVal, _t(CMenu::_NandEmu[i].id, CMenu::_NandEmu[i].text));
|
||||
|
||||
i = min(max(0, m_cfg.getInt(WII_DOMAIN, "save_emulation", 0)), (int)ARRAY_SIZE(CMenu::_GlobalSaveEmu) - 1);
|
||||
m_btnMgr.setText(m_nandemuLblSaveEmulationVal, _t(CMenu::_GlobalSaveEmu[i].id, CMenu::_GlobalSaveEmu[i].text));
|
||||
|
||||
m_btnMgr.setText(m_nandemuLblNandSelectVal, m_cfg.getString(CHANNEL_DOMAIN, "current_emunand"));
|
||||
m_btnMgr.setText(m_nandemuLblSaveNandSelectVal, m_cfg.getString(WII_DOMAIN, "current_save_emunand"));
|
||||
|
||||
m_btnMgr.show(m_nandemuLblNandSelect);
|
||||
m_btnMgr.show(m_nandemuLblNandSelectVal);
|
||||
m_btnMgr.show(m_nandemuBtnNandSelectP);
|
||||
m_btnMgr.show(m_nandemuBtnNandSelectM);
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
m_btnMgr.setText(m_nandemuLblNandSelectVal, m_cfg.getString(CHANNEL_DOMAIN, "current_emunand"));
|
||||
else if(m_current_view == COVERFLOW_WII)
|
||||
m_btnMgr.setText(m_nandemuLblNandSelectVal, m_cfg.getString(WII_DOMAIN, "current_save_emunand"));
|
||||
|
||||
m_btnMgr.show(m_nandemuLblEmulation);
|
||||
m_btnMgr.show(m_nandemuLblEmulationVal);
|
||||
m_btnMgr.show(m_nandemuBtnEmulationP);
|
||||
m_btnMgr.show(m_nandemuBtnEmulationM);
|
||||
|
||||
m_btnMgr.show(m_nandemuLblSaveNandSelect);
|
||||
m_btnMgr.show(m_nandemuLblSaveNandSelectVal);
|
||||
m_btnMgr.show(m_nandemuBtnSaveNandSelectP);
|
||||
m_btnMgr.show(m_nandemuBtnSaveNandSelectM);
|
||||
|
||||
m_btnMgr.show(m_nandemuLblSaveEmulation);
|
||||
m_btnMgr.show(m_nandemuLblSaveEmulationVal);
|
||||
m_btnMgr.show(m_nandemuBtnSaveEmulationP);
|
||||
m_btnMgr.show(m_nandemuBtnSaveEmulationM);
|
||||
}
|
||||
else //page 2
|
||||
{
|
||||
const char *partitionname = DeviceName[m_cfg.getInt(WII_DOMAIN, "savepartition")];
|
||||
m_btnMgr.setText(m_nandemuLblSavePartitionVal, upperCase(partitionname));
|
||||
|
||||
m_btnMgr.show(m_nandemuLblSaveDump);
|
||||
m_btnMgr.show(m_nandemuBtnAll);
|
||||
m_btnMgr.show(m_nandemuBtnMissing);
|
||||
|
||||
m_btnMgr.show(m_nandemuLblNandDump);
|
||||
m_btnMgr.show(m_nandemuBtnNandDump);
|
||||
|
||||
m_btnMgr.show(m_nandemuLblSavePartition);
|
||||
m_btnMgr.show(m_nandemuLblSavePartitionVal);
|
||||
m_btnMgr.show(m_nandemuBtnSavePartitionP);
|
||||
m_btnMgr.show(m_nandemuBtnSavePartitionM);
|
||||
}
|
||||
|
||||
for(u8 i = 0; i < ARRAY_SIZE(m_nandemuLblUser); ++i)
|
||||
@ -336,29 +381,34 @@ int CMenu::_NandEmuCfg(void)
|
||||
nandemuPage = 1;
|
||||
|
||||
vector<string> emuNands;
|
||||
string prevEmuNand;
|
||||
int emuPart;
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
{
|
||||
prevEmuNand = m_cfg.getString(CHANNEL_DOMAIN, "current_emunand");
|
||||
emuPart = m_cfg.getInt(CHANNEL_DOMAIN, "partition");
|
||||
}
|
||||
else
|
||||
{
|
||||
prevEmuNand = m_cfg.getString(WII_DOMAIN, "current_save_emunand");
|
||||
emuPart = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
||||
}
|
||||
vector<string> savesNands;
|
||||
string emuNand = m_cfg.getString(CHANNEL_DOMAIN, "current_emunand");
|
||||
int emuPart = m_cfg.getInt(CHANNEL_DOMAIN, "partition");
|
||||
string savesNand = m_cfg.getString(WII_DOMAIN, "current_save_emunand");
|
||||
int savesPart = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
||||
|
||||
listEmuNands(fmt("%s:/%s", DeviceName[emuPart], EMU_NANDS_DIR), emuNands);
|
||||
int curEmuNand = 0;
|
||||
for(u8 i = 0; i < emuNands.size(); ++i)
|
||||
{
|
||||
if(emuNands[i] == prevEmuNand)
|
||||
if(emuNands[i] == emuNand)
|
||||
{
|
||||
curEmuNand = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
listEmuNands(fmt("%s:/%s", DeviceName[savesPart], EMU_NANDS_DIR), savesNands);
|
||||
int curSavesNand = 0;
|
||||
for(u8 i = 0; i < savesNands.size(); ++i)
|
||||
{
|
||||
if(savesNands[i] == savesNand)
|
||||
{
|
||||
curSavesNand = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lwp_t thread = 0;
|
||||
SetupInput();
|
||||
_showNandEmu();
|
||||
@ -372,39 +422,73 @@ int CMenu::_NandEmuCfg(void)
|
||||
_mainLoopCommon();
|
||||
if((BTN_MINUS_PRESSED || BTN_LEFT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnPageM)))
|
||||
{
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, true);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, true);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, true);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, true);
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, true);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, true);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelect, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelectVal, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectP, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectM, true);
|
||||
bool instant = true;
|
||||
m_btnMgr.hide(m_nandemuLblNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSavePartition, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSavePartitionVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionM, instant);
|
||||
|
||||
nandemuPage = nandemuPage == 1 ? 2 : 1;
|
||||
_showNandEmu();
|
||||
}
|
||||
else if((BTN_PLUS_PRESSED || BTN_RIGHT_PRESSED) || (BTN_A_PRESSED && m_btnMgr.selected(m_nandemuBtnPageP)))
|
||||
{
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, true);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, true);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, true);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, true);
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, true);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, true);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelect, true);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelectVal, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectP, true);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectM, true);
|
||||
bool instant = true;
|
||||
m_btnMgr.hide(m_nandemuLblNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelect, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveNandSelectVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveNandSelectM, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulationVal, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSaveEmulation, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSaveEmulationM, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnAll, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblNandDump, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnNandDump, instant);
|
||||
|
||||
m_btnMgr.hide(m_nandemuLblSavePartition, instant);
|
||||
m_btnMgr.hide(m_nandemuLblSavePartitionVal, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionP, instant);
|
||||
m_btnMgr.hide(m_nandemuBtnSavePartitionM, instant);
|
||||
|
||||
nandemuPage = nandemuPage == 1 ? 2 : 1;
|
||||
_showNandEmu();
|
||||
}
|
||||
@ -414,24 +498,32 @@ int CMenu::_NandEmuCfg(void)
|
||||
m_btnMgr.up();
|
||||
else if(BTN_DOWN_PRESSED)
|
||||
m_btnMgr.down();
|
||||
else if (BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnEmulationP) || m_btnMgr.selected(m_nandemuBtnEmulationM)))
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnEmulationP) || m_btnMgr.selected(m_nandemuBtnEmulationM)))
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_nandemuBtnEmulationP) ? 1 : -1;
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
m_cfg.setInt(CHANNEL_DOMAIN, "emulation", (int)loopNum((u32)m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0) + direction, ARRAY_SIZE(CMenu::_NandEmu)));
|
||||
else if(m_current_view == COVERFLOW_WII)
|
||||
m_cfg.setInt(WII_DOMAIN, "save_emulation", (int)loopNum((u32)m_cfg.getInt(WII_DOMAIN, "save_emulation", 0) + direction, ARRAY_SIZE(CMenu::_GlobalSaveEmu)));
|
||||
m_cfg.setInt(CHANNEL_DOMAIN, "emulation", loopNum(m_cfg.getInt(CHANNEL_DOMAIN, "emulation", 0) + direction, ARRAY_SIZE(CMenu::_NandEmu)));
|
||||
_showNandEmu();
|
||||
}
|
||||
}
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnSaveEmulationP) || m_btnMgr.selected(m_nandemuBtnSaveEmulationM)))
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_nandemuBtnSaveEmulationP) ? 1 : -1;
|
||||
m_cfg.setInt(WII_DOMAIN, "save_emulation", loopNum(m_cfg.getInt(WII_DOMAIN, "save_emulation", 0) + direction, ARRAY_SIZE(CMenu::_GlobalSaveEmu)));
|
||||
_showNandEmu();
|
||||
}
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnSavePartitionP) || m_btnMgr.selected(m_nandemuBtnSavePartitionM)))
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_nandemuBtnSavePartitionP) ? 1 : -1;
|
||||
currentPartition = m_cfg.getInt(WII_DOMAIN, "savepartition");
|
||||
m_emuSaveNand = true;
|
||||
_setPartition(direction);
|
||||
m_emuSaveNand = false;
|
||||
_showNandEmu();
|
||||
}
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnNandDump) || m_btnMgr.selected(m_nandemuBtnAll) || m_btnMgr.selected(m_nandemuBtnMissing)))
|
||||
{
|
||||
m_fulldump = m_btnMgr.selected(m_nandemuBtnNandDump) ? true : false;
|
||||
m_saveall = m_btnMgr.selected(m_nandemuBtnAll) ? true : false;
|
||||
m_btnMgr.hide(m_nandemuBtnBack);
|
||||
m_btnMgr.hide(m_nandemuLblEmulationVal);
|
||||
m_btnMgr.hide(m_nandemuLblEmulation);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationP);
|
||||
m_btnMgr.hide(m_nandemuBtnEmulationM);
|
||||
m_btnMgr.hide(m_nandemuLblSaveDump);
|
||||
m_btnMgr.hide(m_nandemuBtnAll);
|
||||
m_btnMgr.hide(m_nandemuBtnMissing);
|
||||
@ -463,12 +555,16 @@ int CMenu::_NandEmuCfg(void)
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_nandemuBtnNandSelectP) ? 1 : -1;
|
||||
curEmuNand = loopNum(curEmuNand + direction, emuNands.size());
|
||||
if(m_current_view == COVERFLOW_CHANNEL)
|
||||
m_cfg.setString(CHANNEL_DOMAIN, "current_emunand", emuNands[curEmuNand]);
|
||||
else
|
||||
m_cfg.setString(WII_DOMAIN, "current_save_emunand", emuNands[curEmuNand]);
|
||||
m_cfg.setString(CHANNEL_DOMAIN, "current_emunand", emuNands[curEmuNand]);
|
||||
_showNandEmu();
|
||||
}
|
||||
}
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnSaveNandSelectP) || m_btnMgr.selected(m_nandemuBtnSaveNandSelectM)))
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_nandemuBtnSaveNandSelectP) ? 1 : -1;
|
||||
curSavesNand = loopNum(curSavesNand + direction, savesNands.size());
|
||||
m_cfg.setString(WII_DOMAIN, "current_save_emunand", savesNands[curSavesNand]);
|
||||
_showNandEmu();
|
||||
}
|
||||
else if(BTN_A_PRESSED && (m_btnMgr.selected(m_nandemuBtnBack)))
|
||||
{
|
||||
m_cfg.save();
|
||||
@ -502,10 +598,11 @@ int CMenu::_NandEmuCfg(void)
|
||||
}
|
||||
}
|
||||
_hideNandEmu();
|
||||
if(prevEmuNand != m_cfg.getString(CHANNEL_DOMAIN, "current_emunand") && m_current_view == COVERFLOW_CHANNEL)
|
||||
if(emuNand != m_cfg.getString(CHANNEL_DOMAIN, "current_emunand"))
|
||||
{
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "update_cache", true);
|
||||
m_load_view = true;
|
||||
if(m_current_view == COVERFLOW_CHANNEL)// or source is set
|
||||
m_load_view = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -691,143 +788,6 @@ int CMenu::_AutoExtractSave(string gameId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CMenu::_AutoCreateNand(void)
|
||||
{
|
||||
lwp_t thread = 0;
|
||||
SetupInput();
|
||||
m_thrdStop = false;
|
||||
m_thrdMessageAdded = false;
|
||||
m_nandext = false;
|
||||
m_emuSaveNand = false;
|
||||
bool changePart = false;
|
||||
bool lock_part_change = false;
|
||||
|
||||
m_btnMgr.setText(m_nandemuBtnExtract, _t("cfgne5", L"Extract NAND"));
|
||||
m_btnMgr.setText(m_nandemuBtnDisable, _t("cfgne22", L"Disable NAND Emulation"));
|
||||
m_btnMgr.setText(m_nandemuBtnPartition, _t("cfgne31", L"Select Partition"));
|
||||
//might add change nand button
|
||||
m_btnMgr.setText(m_nandemuLblInit, _t("cfgne23", L"Emu NAND not found. Try one of these options to fix the problem."));
|
||||
m_btnMgr.show(m_nandemuBtnExtract);
|
||||
m_btnMgr.show(m_nandemuBtnDisable);
|
||||
m_btnMgr.show(m_nandemuBtnPartition);
|
||||
m_btnMgr.show(m_nandemuLblInit);
|
||||
|
||||
while(!m_exit)
|
||||
{
|
||||
_mainLoopCommon();
|
||||
if(BTN_A_PRESSED)
|
||||
{
|
||||
if(m_btnMgr.selected(m_nandemuBtnExtract))
|
||||
{
|
||||
lock_part_change = true;
|
||||
m_fulldump = true;
|
||||
m_btnMgr.hide(m_nandemuBtnExtract);
|
||||
m_btnMgr.hide(m_nandemuBtnDisable);
|
||||
m_btnMgr.hide(m_nandemuBtnPartition);
|
||||
m_btnMgr.hide(m_nandemuLblInit);
|
||||
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("cfgne12", L"NAND Extractor"));
|
||||
m_thrdStop = false;
|
||||
m_thrdProgress = 0.f;
|
||||
m_thrdWorking = true;
|
||||
LWP_CreateThread(&thread, (void *(*)(void *))CMenu::_NandDumper, (void *)this, 0, 32768, 40);
|
||||
}
|
||||
else if(m_btnMgr.selected(m_nandemuBtnDisable))
|
||||
{
|
||||
_hideNandEmu();
|
||||
return 0;
|
||||
}
|
||||
else if(m_btnMgr.selected(m_nandemuBtnPartition))
|
||||
{
|
||||
m_btnMgr.hide(m_nandemuBtnExtract);
|
||||
m_btnMgr.hide(m_nandemuBtnDisable);
|
||||
m_btnMgr.hide(m_nandemuBtnPartition);
|
||||
m_btnMgr.hide(m_nandemuLblInit);
|
||||
m_btnMgr.show(m_configLblPartitionName);
|
||||
m_btnMgr.show(m_configLblPartition);
|
||||
m_btnMgr.show(m_configBtnPartitionP);
|
||||
m_btnMgr.show(m_configBtnPartitionM);
|
||||
m_btnMgr.show(m_nandemuBtnBack);
|
||||
changePart = true;
|
||||
}
|
||||
else if(m_btnMgr.selected(m_configBtnPartitionP) || m_btnMgr.selected(m_configBtnPartitionM))
|
||||
{
|
||||
s8 direction = m_btnMgr.selected(m_configBtnPartitionP) ? 1 : -1;
|
||||
u8 limiter = 0;
|
||||
do
|
||||
{
|
||||
currentPartition = loopNum(currentPartition + direction, 9);
|
||||
limiter++;
|
||||
}
|
||||
while(limiter < 9 && !DeviceHandle.PartitionUsableForNandEmu(currentPartition));
|
||||
//if limiter = 9 error
|
||||
m_btnMgr.setText(m_configLblPartition, upperCase(DeviceName[currentPartition]));
|
||||
}
|
||||
else if(m_btnMgr.selected(m_nandemuBtnBack))
|
||||
{
|
||||
if(changePart)
|
||||
{
|
||||
m_btnMgr.hide(m_configLblPartitionName);
|
||||
m_btnMgr.hide(m_configLblPartition);
|
||||
m_btnMgr.hide(m_configBtnPartitionP);
|
||||
m_btnMgr.hide(m_configBtnPartitionM);
|
||||
m_btnMgr.hide(m_nandemuBtnBack);
|
||||
if(m_current_view == COVERFLOW_WII)
|
||||
m_cfg.setInt(WII_DOMAIN, "savepartition", currentPartition);
|
||||
else
|
||||
m_cfg.setInt(CHANNEL_DOMAIN, "partition", currentPartition);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cfg.save();//why save?
|
||||
_hideNandEmu();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(BTN_B_HELD && BTN_MINUS_PRESSED && !lock_part_change)
|
||||
{
|
||||
_setPartition(1);
|
||||
_hideNandEmu();
|
||||
return 1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
m_btnMgr.setText(m_nandfinLblDialog, wfmt(_fmt("cfgne15", L"Extracted: %d files / %d folders"), 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));
|
||||
m_btnMgr.show(m_nandemuBtnBack);
|
||||
m_btnMgr.show(m_nandfinLblDialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
_hideNandEmu();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CMenu::_NandFlasher(void *obj)
|
||||
{
|
||||
CMenu &m = *(CMenu *)obj;
|
||||
@ -877,7 +837,7 @@ int CMenu::_NandDumper(void *obj)
|
||||
m.m_foldersdone = 0;
|
||||
|
||||
NandHandle.ResetCounters();
|
||||
emuPartition = m._FindEmuPart(emuPath, true, (m.m_current_view == COVERFLOW_WII));
|
||||
emuPartition = m._FindEmuPart(emuPath, true, !m_fulldump);
|
||||
|
||||
if(emuPartition < 0)
|
||||
{
|
||||
@ -983,20 +943,32 @@ void CMenu::_initNandEmuMenu()
|
||||
m_nandfilePBar = _addProgressBar("NANDEMU/FILEPROGRESS_BAR", 40, 200, 560, 20);
|
||||
m_nandemuPBar = _addProgressBar("NANDEMU/PROGRESS_BAR", 40, 200, 560, 20);
|
||||
|
||||
m_nandemuLblEmulation = _addLabel("NANDEMU/EMU_SAVE", theme.lblFont, L"", 20, 125, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblEmulationVal = _addLabel("NANDEMU/EMU_SAVE_BTN_GLOBAL", theme.btnFont, L"", 468, 130, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnEmulationM = _addPicButton("NANDEMU/EMU_SAVE_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 130, 48, 48);
|
||||
m_nandemuBtnEmulationP = _addPicButton("NANDEMU/EMU_SAVE_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 130, 48, 48);
|
||||
m_nandemuLblSaveDump = _addLabel("NANDEMU/SAVE_DUMP", theme.lblFont, L"", 20, 185, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuBtnAll = _addButton("NANDEMU/ALL_BTN", theme.btnFont, L"", 420, 190, 200, 48, theme.btnFontColor);
|
||||
m_nandemuBtnMissing = _addButton("NANDEMU/MISSING_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor);
|
||||
m_nandemuLblNandDump = _addLabel("NANDEMU/NAND_DUMP", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuBtnNandDump = _addButton("NANDEMU/NAND_DUMP_BTN", theme.btnFont, L"", 420, 310, 200, 48, theme.btnFontColor);
|
||||
|
||||
m_nandemuLblNandSelect = _addLabel("NANDEMU/NAND_SELECT", theme.lblFont, L"", 20, 125, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblNandSelectVal = _addLabel("NANDEMU/NAND_SELECT_BTN", theme.btnFont, L"", 468, 130, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnNandSelectM = _addPicButton("NANDEMU/NAND_SELECT_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 130, 48, 48);
|
||||
m_nandemuBtnNandSelectP = _addPicButton("NANDEMU/NAND_SELECT_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 130, 48, 48);
|
||||
m_nandemuLblEmulation = _addLabel("NANDEMU/NAND_EMU", theme.lblFont, L"", 20, 185, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblEmulationVal = _addLabel("NANDEMU/NAND_EMU_BTN", theme.btnFont, L"", 468, 190, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnEmulationM = _addPicButton("NANDEMU/NAND_EMU_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 190, 48, 48);
|
||||
m_nandemuBtnEmulationP = _addPicButton("NANDEMU/NAND_EMU_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 190, 48, 48);
|
||||
m_nandemuLblSaveNandSelect = _addLabel("NANDEMU/SAVE_NAND_SELECT", theme.lblFont, L"", 20, 245, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblSaveNandSelectVal = _addLabel("NANDEMU/SAVE_NAND_SELECT_BTN", theme.btnFont, L"", 468, 250, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnSaveNandSelectM = _addPicButton("NANDEMU/SAVE_NAND_SELECT_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 250, 48, 48);
|
||||
m_nandemuBtnSaveNandSelectP = _addPicButton("NANDEMU/SAVE_NAND_SELECT_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 250, 48, 48);
|
||||
m_nandemuLblSaveEmulation = _addLabel("NANDEMU/SAVE_EMU", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblSaveEmulationVal = _addLabel("NANDEMU/SAVE_EMU_BTN", theme.btnFont, L"", 468, 310, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnSaveEmulationM = _addPicButton("NANDEMU/SAVE_EMU_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 310, 48, 48);
|
||||
m_nandemuBtnSaveEmulationP = _addPicButton("NANDEMU/SAVE_EMU_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 310, 48, 48);
|
||||
|
||||
m_nandemuLblSaveDump = _addLabel("NANDEMU/SAVE_DUMP", theme.lblFont, L"", 20, 125, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuBtnAll = _addButton("NANDEMU/ALL_BTN", theme.btnFont, L"", 420, 130, 200, 48, theme.btnFontColor);
|
||||
m_nandemuBtnMissing = _addButton("NANDEMU/MISSING_BTN", theme.btnFont, L"", 420, 190, 200, 48, theme.btnFontColor);
|
||||
m_nandemuLblNandDump = _addLabel("NANDEMU/NAND_DUMP", theme.lblFont, L"", 20, 245, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuBtnNandDump = _addButton("NANDEMU/NAND_DUMP_BTN", theme.btnFont, L"", 420, 250, 200, 48, theme.btnFontColor);
|
||||
m_nandemuLblSavePartition = _addLabel("NANDEMU/SAVE_PART", theme.lblFont, L"", 20, 305, 385, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
|
||||
m_nandemuLblSavePartitionVal = _addLabel("NANDEMU/SAVE_PART_BTN", theme.btnFont, L"", 468, 310, 104, 48, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
|
||||
m_nandemuBtnSavePartitionM = _addPicButton("NANDEMU/SAVE_PART_MINUS", theme.btnTexMinus, theme.btnTexMinusS, 420, 310, 48, 48);
|
||||
m_nandemuBtnSavePartitionP = _addPicButton("NANDEMU/SAVE_PART_PLUS", theme.btnTexPlus, theme.btnTexPlusS, 572, 310, 48, 48);
|
||||
|
||||
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);
|
||||
@ -1017,20 +989,32 @@ void CMenu::_initNandEmuMenu()
|
||||
_setHideAnim(m_nandfilePBar, "NANDEMU/FILEPROGRESS_BAR", 0, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuPBar, "NANDEMU/PROGRESS_BAR", 0, 0, -2.f, 0.f);
|
||||
|
||||
_setHideAnim(m_nandemuLblEmulation, "NANDEMU/EMU_SAVE", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblEmulationVal, "NANDEMU/EMU_SAVE_BTN_GLOBAL", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnEmulationM, "NANDEMU/EMU_SAVE_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnEmulationP, "NANDEMU/EMU_SAVE_PLUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblNandSelect, "NANDEMU/NAND_SELECT", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblNandSelectVal, "NANDEMU/NAND_SELECT_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnNandSelectM, "NANDEMU/NAND_SELECT_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnNandSelectP, "NANDEMU/NAND_SELECT_PLUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblEmulation, "NANDEMU/NAND_EMU", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblEmulationVal, "NANDEMU/NAND_EMU_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnEmulationM, "NANDEMU/NAND_EMU_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnEmulationP, "NANDEMU/NAND_EMU_PLUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSaveNandSelect, "NANDEMU/SAVE_NAND_SELECT", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSaveNandSelectVal, "NANDEMU/SAVE_NAND_SELECT_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSaveNandSelectM, "NANDEMU/SAVE_NAND_SELECT_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSaveNandSelectP, "NANDEMU/SAVE_NAND_SELECT_PLUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSaveEmulation, "NANDEMU/SAVE_EMU", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSaveEmulationVal, "NANDEMU/SAVE_EMU_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSaveEmulationM, "NANDEMU/SAVE_EMU_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSaveEmulationP, "NANDEMU/SAVE_EMU_PLUS", -50, 0, 1.f, 0.f);
|
||||
|
||||
_setHideAnim(m_nandemuLblSaveDump, "NANDEMU/SAVE_DUMP", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnAll, "NANDEMU/ALL_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnMissing, "NANDEMU/MISSING_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblNandDump, "NANDEMU/NAND_DUMP", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnNandDump, "NANDEMU/NAND_DUMP_BTN", -50, 0, 1.f, 0.f);
|
||||
|
||||
_setHideAnim(m_nandemuLblNandSelect, "NANDEMU/NAND_SELECT", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblNandSelectVal, "NANDEMU/NAND_SELECT_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnNandSelectM, "NANDEMU/NAND_SELECT_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnNandSelectP, "NANDEMU/NAND_SELECT_PLUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSavePartition, "NANDEMU/SAVE_PART", 50, 0, -2.f, 0.f);
|
||||
_setHideAnim(m_nandemuLblSavePartitionVal, "NANDEMU/SAVE_PART_BTN", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSavePartitionM, "NANDEMU/SAVE_PART_MINUS", -50, 0, 1.f, 0.f);
|
||||
_setHideAnim(m_nandemuBtnSavePartitionP, "NANDEMU/SAVE_PART_PLUS", -50, 0, 1.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);
|
||||
@ -1048,8 +1032,11 @@ void CMenu::_initNandEmuMenu()
|
||||
|
||||
void CMenu::_textNandEmu(void)
|
||||
{
|
||||
m_btnMgr.setText(m_nandemuLblNandSelect, _t("cfgne37", L"Select Nand"));
|
||||
m_btnMgr.setText(m_nandemuLblNandSelect, _t("cfgne37", L"Select NAND"));
|
||||
m_btnMgr.setText(m_nandemuLblEmulation, _t("cfgne1", L"NAND Emulation"));
|
||||
m_btnMgr.setText(m_nandemuLblSaveNandSelect, _t("cfgne32", L"Select Saves NAND"));
|
||||
m_btnMgr.setText(m_nandemuLblSaveEmulation, _t("cfgne33", L"Saves NAND Emulation"));
|
||||
m_btnMgr.setText(m_nandemuLblSavePartition, _t("cfgne38", L"Saves NAND Partition"));
|
||||
m_btnMgr.setText(m_nandemuLblSaveDump, _t("cfgne2", L"Extract Game Saves"));
|
||||
m_btnMgr.setText(m_nandemuBtnAll, _t("cfgne3", L"All"));
|
||||
m_btnMgr.setText(m_nandemuBtnMissing, _t("cfgne4", L"Missing"));
|
||||
|
@ -146,6 +146,7 @@ void CMenu::_PluginSettings()
|
||||
{
|
||||
if(m_btnMgr.selected(m_pluginBtn[i]))
|
||||
{
|
||||
m_load_view = true;
|
||||
if(i == 0)
|
||||
{
|
||||
m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
@ -161,8 +162,13 @@ void CMenu::_PluginSettings()
|
||||
}
|
||||
}
|
||||
_hidePluginSettings();
|
||||
//_loadList();
|
||||
m_load_view = true;
|
||||
m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(m_load_view || (m_current_view != COVERFLOW_PLUGIN && enabledPluginsCount > 0))
|
||||
{
|
||||
m_current_view = COVERFLOW_PLUGIN;
|
||||
_clearSources();
|
||||
m_cfg.setBool(_domainFromView(), "source", true);
|
||||
}
|
||||
}
|
||||
|
||||
void CMenu::_initPluginSettingsMenu()
|
||||
|
@ -17,7 +17,8 @@ s16 m_sourceLblUser[4];
|
||||
|
||||
TexData m_sourceBg;
|
||||
|
||||
string source, themeName;
|
||||
string source;
|
||||
const char *themeName = NULL;
|
||||
bool exitSource = false;
|
||||
u8 sourceBtn;
|
||||
u8 selectedBtns;
|
||||
@ -179,7 +180,7 @@ void CMenu::_updateSourceBtns(void)
|
||||
if(btnSource == "allplugins")
|
||||
{
|
||||
const vector<bool> &EnabledPlugins = m_plugin.GetEnabledPlugins(m_cfg, &enabledPluginsCount);
|
||||
if(EnabledPlugins.size() == 0)//all plugns enabled
|
||||
if(EnabledPlugins.size() == 0)//all plugins enabled
|
||||
{
|
||||
sourceBtn = i;
|
||||
selectedBtns++;
|
||||
@ -193,23 +194,27 @@ void CMenu::_updateSourceBtns(void)
|
||||
u32 magic = strtoul(magicNums.at(0).c_str(), NULL, 16);
|
||||
if(m_plugin.GetEnableStatus(m_cfg, magic))
|
||||
{
|
||||
m_cfg.setBool(PLUGIN_DOMAIN, "source", true);
|
||||
sourceBtn = i;
|
||||
selectedBtns++;
|
||||
btn_image = btn_imageSel;
|
||||
if(m_cfg.getBool(PLUGIN_DOMAIN, "source", false))
|
||||
{
|
||||
sourceBtn = i;
|
||||
selectedBtns++;
|
||||
btn_image = btn_imageSel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((btnSource == "realnand" && m_cfg.getBool(CHANNEL_DOMAIN, "real_nand", false)) ||
|
||||
(btnSource == "emunand" && m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand", false)))
|
||||
{
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "source", true);
|
||||
sourceBtn = i;
|
||||
selectedBtns++;
|
||||
btn_image = btn_imageSel;
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "source", false))
|
||||
{
|
||||
sourceBtn = i;
|
||||
selectedBtns++;
|
||||
btn_image = btn_imageSel;
|
||||
}
|
||||
}
|
||||
else if(btnSource == "dml" || btnSource == "homebrew" || btnSource == "wii")
|
||||
{
|
||||
string domain = (btnSource == "dml" ? GC_DOMAIN : (btnSource == "homebrew" ? HOMEBREW_DOMAIN : WII_DOMAIN));
|
||||
const char *domain = (btnSource == "dml" ? GC_DOMAIN : (btnSource == "homebrew" ? HOMEBREW_DOMAIN : WII_DOMAIN));
|
||||
if(m_cfg.getBool(domain, "source", false))
|
||||
{
|
||||
sourceBtn = i;
|
||||
@ -222,12 +227,12 @@ void CMenu::_updateSourceBtns(void)
|
||||
{
|
||||
TexData texConsoleImg;
|
||||
TexData texConsoleImgs;
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s/%s", m_sourceDir.c_str(), themeName.c_str(), btn_image)) != TE_OK)
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s/%s", m_sourceDir.c_str(), themeName, btn_image)) != TE_OK)
|
||||
{
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s", m_sourceDir.c_str(), btn_image)) != TE_OK)
|
||||
TexHandle.fromImageFile(texConsoleImg, fmt("%s/favoriteson.png", m_imgsDir.c_str()));
|
||||
}
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s/%s", m_sourceDir.c_str(), themeName.c_str(), btn_image)) != TE_OK)
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s/%s", m_sourceDir.c_str(), themeName, btn_image)) != TE_OK)
|
||||
{
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s", m_sourceDir.c_str(), btn_image)) != TE_OK)
|
||||
TexHandle.fromImageFile(texConsoleImgs, fmt("%s/favoritesons.png", m_imgsDir.c_str()));
|
||||
@ -423,7 +428,7 @@ bool CMenu::_Source()
|
||||
}
|
||||
else if(source == "homebrew")
|
||||
{
|
||||
if(!show_homebrew)
|
||||
if((m_locked || m_cfg.getBool(HOMEBREW_DOMAIN, "parental", false)))
|
||||
_showSourceNotice();
|
||||
else
|
||||
{
|
||||
@ -496,9 +501,25 @@ bool CMenu::_Source()
|
||||
if(show_channel)
|
||||
{
|
||||
if(source == "realnand")
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", !m_cfg.getBool(CHANNEL_DOMAIN, "real_nand"));
|
||||
{
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "source"))
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", !m_cfg.getBool(CHANNEL_DOMAIN, "real_nand"));
|
||||
else
|
||||
{
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", true);
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", false);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", !m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand"));
|
||||
{
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "source"))
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", !m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand"));
|
||||
else
|
||||
{
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "emu_nand", true);
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "real_nand", false);
|
||||
}
|
||||
}
|
||||
if(m_cfg.getBool(CHANNEL_DOMAIN, "emu_nand") || m_cfg.getBool(CHANNEL_DOMAIN, "real_nand"))
|
||||
m_cfg.setBool(CHANNEL_DOMAIN, "source", true);
|
||||
else
|
||||
@ -507,7 +528,7 @@ bool CMenu::_Source()
|
||||
}
|
||||
else if(source == "homebrew")
|
||||
{
|
||||
if(show_homebrew)
|
||||
if((!m_locked || !m_cfg.getBool(HOMEBREW_DOMAIN, "parental", false)))
|
||||
m_cfg.setBool(HOMEBREW_DOMAIN, "source", !m_cfg.getBool(HOMEBREW_DOMAIN, "source"));
|
||||
}
|
||||
else if(source == "allplugins")
|
||||
@ -524,6 +545,11 @@ bool CMenu::_Source()
|
||||
{
|
||||
if(show_plugin)
|
||||
{
|
||||
if(!m_cfg.getBool(PLUGIN_DOMAIN, "source"))
|
||||
{
|
||||
for(j = 0; m_plugin.PluginExist(j); ++j) /* clear all */
|
||||
m_plugin.SetEnablePlugin(m_cfg, j, 1);
|
||||
}
|
||||
magicNums.clear();
|
||||
magicNums = m_source.getStrings(btn_selected, "magic", ',');
|
||||
if(!magicNums.empty())
|
||||
@ -566,7 +592,6 @@ bool CMenu::_Source()
|
||||
return newSource;
|
||||
}
|
||||
|
||||
//letters in lower case only
|
||||
static const char sideCovers[4][9] = {
|
||||
"534e5854", //Snes9X-Next
|
||||
"534e4553", //SNES9xGX
|
||||
@ -595,7 +620,7 @@ bool CMenu::_sideCover(const char *magic)
|
||||
return false;
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
if(memcmp(magic, sideCovers[i], 9) == 0)
|
||||
if(strncasecmp(magic, sideCovers[i], 8) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -607,7 +632,7 @@ bool CMenu::_shortCover(const char *magic)
|
||||
return false;
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
if(memcmp(magic, shortCovers[i], 9) == 0)
|
||||
if(strncasecmp(magic, shortCovers[i], 8) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -678,14 +703,14 @@ void CMenu::_clearSources(void)
|
||||
void CMenu::_initSourceMenu()
|
||||
{
|
||||
m_use_source = false;
|
||||
themeName = m_cfg.getString("GENERAL", "theme", "default");
|
||||
if(!m_source.load(fmt("%s/%s/%s", m_sourceDir.c_str(), themeName.c_str(), SOURCE_FILENAME)))
|
||||
themeName = m_cfg.getString("GENERAL", "theme", "default").c_str();
|
||||
if(!m_source.load(fmt("%s/%s/%s", m_sourceDir.c_str(), themeName, SOURCE_FILENAME)))
|
||||
{
|
||||
if(!m_source.load(fmt("%s/%s", m_sourceDir.c_str(), SOURCE_FILENAME)))
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_sourceDir = fmt("%s/%s", m_sourceDir.c_str(), themeName.c_str());
|
||||
m_sourceDir = fmt("%s/%s", m_sourceDir.c_str(), themeName);
|
||||
|
||||
m_use_source = true;
|
||||
|
||||
@ -701,28 +726,28 @@ void CMenu::_initSourceMenu()
|
||||
|
||||
int row;
|
||||
int col;
|
||||
string ImgName;
|
||||
const char *ImgName = NULL;
|
||||
|
||||
for(i = 0; i < 12; ++i)
|
||||
{
|
||||
TexData texConsoleImg;
|
||||
TexData texConsoleImgs;
|
||||
ImgName = m_source.getString(fmt("BUTTON_%i", i),"image", "");
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s", m_themeDataDir.c_str(), ImgName.c_str())) != TE_OK)
|
||||
ImgName = m_source.getString(fmt("BUTTON_%i", i),"image", "").c_str();
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s", m_themeDataDir.c_str(), ImgName)) != TE_OK)
|
||||
{
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s", m_sourceDir.c_str(), ImgName.c_str())) != TE_OK)
|
||||
if(TexHandle.fromImageFile(texConsoleImg, fmt("%s/%s", m_sourceDir.c_str(), ImgName)) != TE_OK)
|
||||
TexHandle.fromImageFile(texConsoleImg, fmt("%s/favoriteson.png", m_imgsDir.c_str()));
|
||||
}
|
||||
ImgName = m_source.getString(fmt("BUTTON_%i", i),"image_s", "");
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s", m_themeDataDir.c_str(), ImgName.c_str())) != TE_OK)
|
||||
ImgName = m_source.getString(fmt("BUTTON_%i", i),"image_s", "").c_str();
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s", m_themeDataDir.c_str(), ImgName)) != TE_OK)
|
||||
{
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s", m_sourceDir.c_str(), ImgName.c_str())) != TE_OK)
|
||||
if(TexHandle.fromImageFile(texConsoleImgs, fmt("%s/%s", m_sourceDir.c_str(), ImgName)) != TE_OK)
|
||||
TexHandle.fromImageFile(texConsoleImgs, fmt("%s/favoritesons.png", m_imgsDir.c_str()));
|
||||
}
|
||||
|
||||
row = i / 4;
|
||||
col = i - (row * 4);
|
||||
m_sourceBtnSource[i] = _addPicButton(fmt("SOURCE/SOURCE_BTN_%i", i), texConsoleImg, texConsoleImgs, (100 + 120 * col), (90 + 100 * row), 80, 80);
|
||||
m_sourceBtnSource[i] = _addPicButton(fmt("SOURCE/SOURCE_BTN_%i", i), texConsoleImg, texConsoleImgs, (100 + 120 * col), (90 + 100 * row), 100, 80);
|
||||
_setHideAnim(m_sourceBtnSource[i], fmt("SOURCE/SOURCE_BTN_%i", i), 0, 0, -2.f, 0.f);
|
||||
}
|
||||
_setHideAnim(m_sourceLblTitle, "SOURCE/TITLE", 0, 0, -2.f, 0.f);
|
||||
|
@ -1,371 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2013 FIX94
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include "FTP_Dir.hpp"
|
||||
#include "ftp.h"
|
||||
#include "net.h"
|
||||
#include "gecko/gecko.hpp"
|
||||
#include "devicemounter/DeviceHandler.hpp"
|
||||
#include "fileOps/fileOps.h"
|
||||
#include "gui/fmt.h"
|
||||
#include "loader/wbfs.h"
|
||||
#include "memory/mem2.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
char main_path[MAXPATHLEN];
|
||||
char real_path[MAXPATHLEN];
|
||||
u8 cur_part = 0;
|
||||
|
||||
char dbg_messages[6][128];
|
||||
|
||||
void ftp_init(void)
|
||||
{
|
||||
memset(main_path, 0, MAXPATHLEN);
|
||||
main_path[0] = '/';
|
||||
memset(real_path, 0, MAXPATHLEN);
|
||||
cur_part = 0;
|
||||
for(u8 i = 0; i < 6; ++i)
|
||||
memset(dbg_messages[i], 0, 128);
|
||||
}
|
||||
|
||||
const char *ftp_getpath(void)
|
||||
{
|
||||
return main_path;
|
||||
}
|
||||
|
||||
static bool check_device(void)
|
||||
{
|
||||
u8 i;
|
||||
cur_part = 0;
|
||||
for(i = 0; i < MAXDEVICES; ++i)
|
||||
{
|
||||
if(strncmp(DeviceName[i], main_path+1, strlen(DeviceName[i])) == 0)
|
||||
{
|
||||
cur_part = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool change_real_dir(void)
|
||||
{
|
||||
if(main_path[1] == '\0')
|
||||
return true;
|
||||
if(check_device() == true)
|
||||
{
|
||||
strncpy(real_path, fmt("%s:/%s", DeviceName[cur_part], strchr((main_path+1), '/')+1), MAXPATHLEN);
|
||||
if(!fsop_FolderExist(real_path))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
errno = ENODEV;
|
||||
return false;
|
||||
}
|
||||
|
||||
DIR *ftp_diropen()
|
||||
{
|
||||
DIR *cur_dir = NULL;
|
||||
if(main_path[1] != '\0')
|
||||
cur_dir = opendir(real_path);
|
||||
if(cur_dir == NULL)
|
||||
errno = EIO;
|
||||
return cur_dir;
|
||||
}
|
||||
|
||||
int ftp_dirnext(DIR *dir, char *name)
|
||||
{
|
||||
int ret = -1;
|
||||
if(main_path[1] == '\0')
|
||||
{
|
||||
while(cur_part < MAXDEVICES)
|
||||
{
|
||||
if(DeviceHandle.IsInserted(cur_part) && DeviceHandle.GetFSType(cur_part) != PART_FS_WBFS)
|
||||
{
|
||||
strncpy(name, DeviceName[cur_part], 8);
|
||||
cur_part++;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
cur_part++;
|
||||
}
|
||||
}
|
||||
else if(dir != NULL)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
struct dirent *pent = readdir(dir);
|
||||
if(pent == NULL)
|
||||
break;
|
||||
else if(pent->d_name[0] == '.')
|
||||
continue;
|
||||
strncpy(name, pent->d_name, MAXPATHLEN);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ftp_dirclose(DIR *dir)
|
||||
{
|
||||
if(dir != NULL)
|
||||
closedir(dir);
|
||||
dir = NULL;
|
||||
}
|
||||
|
||||
int ftp_changedir(char *path)
|
||||
{
|
||||
int ret = -1;
|
||||
/* main changing */
|
||||
if(strcmp(path, "..") == 0)
|
||||
{
|
||||
/* not in root */
|
||||
if(strlen(main_path) > 1)
|
||||
{
|
||||
/* remove new / */
|
||||
if(strchr(main_path, '/') != NULL)
|
||||
{
|
||||
*(strrchr(main_path, '/')) = '\0';
|
||||
/* remove the path before the new / */
|
||||
if(strchr(main_path, '/') != NULL)
|
||||
*(strrchr(main_path, '/')+1) = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* enter a new path, do some checks */
|
||||
{
|
||||
if(path[0] == '/') /* full path */
|
||||
strcpy(main_path, path);
|
||||
else
|
||||
strcat(main_path, path);
|
||||
}
|
||||
char *last = (main_path+strlen(main_path)-1);
|
||||
if(*last != '/')
|
||||
{
|
||||
*(last+1) = '/';
|
||||
*(last+2) = '\0';
|
||||
}
|
||||
if(change_real_dir() == true)
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ftp_makedir(char *path)
|
||||
{
|
||||
int ret = -1;
|
||||
if(strchr(path, '/') != NULL)
|
||||
{
|
||||
char *real_path = strrchr(path, '/') + 1;
|
||||
if(real_path != '\0')
|
||||
{
|
||||
*strrchr(path, '/') = '\0';
|
||||
ftp_changedir(path);
|
||||
path = real_path;
|
||||
}
|
||||
}
|
||||
if(main_path[1] != '\0')
|
||||
{
|
||||
char *new_dir = fmt("%s%s", real_path, path);
|
||||
fsop_MakeFolder(new_dir);
|
||||
if(fsop_FolderExist(new_dir) == true)
|
||||
ret = 0;
|
||||
}
|
||||
if(ret < 0)
|
||||
errno = EACCES;
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE *ftp_fopen(char *path, char *type)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
if(main_path[1] != '\0')
|
||||
{
|
||||
char *new_file = fmt("%s%s", real_path, path);
|
||||
fp = fopen(new_file, type);
|
||||
if(fp != NULL)
|
||||
gprintf("Opening file %s in type %s\n", new_file, type);
|
||||
}
|
||||
if(fp == NULL)
|
||||
errno = (strcmp(type, "rb") == 0 ? EACCES : EROFS);
|
||||
return fp;
|
||||
}
|
||||
|
||||
void ftp_fclose(FILE *fp)
|
||||
{
|
||||
if(fp != NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
gprintf("Closing file\n");
|
||||
}
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
int ftp_stat(char *file, struct stat *st)
|
||||
{
|
||||
if(file == NULL || st == NULL)
|
||||
return -1;
|
||||
st->st_mtime = 0;
|
||||
st->st_size = 0;
|
||||
st->st_mode = 0;
|
||||
if(main_path[1] == '\0')
|
||||
st->st_mode |= S_IFDIR;
|
||||
else
|
||||
stat(fmt("%s%s", real_path, file), st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ftp_rename(char *path, char *new_name)
|
||||
{
|
||||
int ret = -1;
|
||||
char *old_path = fmt("%s%s", real_path, path);
|
||||
char *new_path = fmt("%s%s", real_path, new_name);
|
||||
if(fsop_FileExist(old_path))
|
||||
{
|
||||
gprintf("Renaming File %s to %s\n", old_path, new_path);
|
||||
ret = rename(old_path, new_path);
|
||||
}
|
||||
else if(fsop_FolderExist(old_path))
|
||||
{
|
||||
gprintf("Renaming Folder %s to %s\n", old_path, new_path);
|
||||
ret = rename(old_path, new_path);
|
||||
}
|
||||
if(ret < 0)
|
||||
errno = EIO;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ftp_delete(char *path)
|
||||
{
|
||||
int ret = -1;
|
||||
char *old_path = fmt("%s%s", real_path, path);
|
||||
if(fsop_FileExist(old_path))
|
||||
{
|
||||
gprintf("%s is a file, deleting it\n", old_path);
|
||||
fsop_deleteFile(old_path);
|
||||
ret = 0;
|
||||
}
|
||||
else if(fsop_FolderExist(old_path))
|
||||
{
|
||||
gprintf("%s is a folder, deleting it\n", old_path);
|
||||
fsop_deleteFolder(old_path);
|
||||
ret = 0;
|
||||
}
|
||||
if(ret < 0)
|
||||
errno = ENOENT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
lwp_t ftpThrdPtr = LWP_THREAD_NULL;
|
||||
u8 *ftpThrdStack = NULL;
|
||||
static const u32 ftpThrdStackSize = 81920; //we need a big stack for all the transfers
|
||||
volatile bool ftpThrd_running = false;
|
||||
bool end_ftp = false;
|
||||
s32 cur_server_num = -1;
|
||||
|
||||
void *ftp_loopThrd(void *nothing)
|
||||
{
|
||||
while(end_ftp == false)
|
||||
{
|
||||
process_ftp_events(cur_server_num);
|
||||
usleep(100);
|
||||
}
|
||||
ftpThrd_running = false;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
bool ftp_startThread(void)
|
||||
{
|
||||
ftp_endTread();
|
||||
if(create_server() == false)
|
||||
return false;
|
||||
cur_server_num = get_server_num();
|
||||
if(cur_server_num < 0)
|
||||
return false;
|
||||
|
||||
end_ftp = false;
|
||||
ftpThrd_running = true;
|
||||
ftpThrdStack = (u8*)MEM2_memalign(32, ftpThrdStackSize);
|
||||
if(ftpThrdStack != NULL)
|
||||
{
|
||||
memset(ftpThrdStack, 0, ftpThrdStackSize);
|
||||
DCFlushRange(ftpThrdStack, ftpThrdStackSize);
|
||||
LWP_CreateThread(&ftpThrdPtr, ftp_loopThrd, NULL, ftpThrdStack, ftpThrdStackSize, 64);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ftp_endTread(void)
|
||||
{
|
||||
if(ftpThrdPtr == LWP_THREAD_NULL)
|
||||
return;
|
||||
|
||||
if(LWP_ThreadIsSuspended(ftpThrdPtr))
|
||||
LWP_ResumeThread(ftpThrdPtr);
|
||||
end_ftp = true;
|
||||
while(ftpThrd_running)
|
||||
usleep(50);
|
||||
LWP_JoinThread(ftpThrdPtr, NULL);
|
||||
ftpThrdPtr = LWP_THREAD_NULL;
|
||||
|
||||
if(ftpThrdStack != NULL)
|
||||
MEM2_free(ftpThrdStack);
|
||||
ftpThrdStack = NULL;
|
||||
|
||||
end_server();
|
||||
cur_server_num = -1;
|
||||
}
|
||||
|
||||
bool dbg_msg_change = false;
|
||||
void ftp_dbg_print(char *dbg_info)
|
||||
{
|
||||
dbg_msg_change = true;
|
||||
/* for gecko and stuff */
|
||||
gprintf(dbg_info);
|
||||
/* for our gui */
|
||||
for(u8 i = 5; i > 0; --i)
|
||||
memcpy(dbg_messages[i], dbg_messages[i-1], 128);
|
||||
memcpy(dbg_messages[0], dbg_info, 127);
|
||||
*(dbg_messages[0]+127) = '\0';
|
||||
}
|
||||
|
||||
const char *ftp_get_prints(u8 i)
|
||||
{
|
||||
return dbg_messages[i];
|
||||
}
|
||||
|
||||
bool ftp_dbg_print_update(void)
|
||||
{
|
||||
if(dbg_msg_change)
|
||||
{
|
||||
dbg_msg_change = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
@ -1,57 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2013 FIX94
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _FTP_DIR_H_
|
||||
#define _FTP_DIR_H_
|
||||
|
||||
#include <sys/reent.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <gctypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void ftp_init(void);
|
||||
const char *ftp_getpath(void);
|
||||
|
||||
DIR *ftp_diropen();
|
||||
void ftp_dirclose(DIR *dir);
|
||||
int ftp_dirnext(DIR *dir, char *name);
|
||||
int ftp_changedir(char *path);
|
||||
int ftp_makedir(char *path);
|
||||
|
||||
FILE *ftp_fopen(char *path, char *type);
|
||||
void ftp_fclose(FILE *fp);
|
||||
|
||||
int ftp_stat(char *file, struct stat *st);
|
||||
int ftp_rename(char *path, char *new_name);
|
||||
int ftp_delete(char *path);
|
||||
|
||||
bool ftp_startThread(void);
|
||||
void ftp_endTread(void);
|
||||
|
||||
void ftp_dbg_print(char *dbg_info);
|
||||
bool ftp_dbg_print_update(void);
|
||||
const char *ftp_get_prints(u8 i);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
@ -1,791 +0,0 @@
|
||||
// Copyright 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <network.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "gui/fmt.h"
|
||||
#include "gecko/gecko.hpp"
|
||||
#include "defines.h"
|
||||
#include "svnrev.h"
|
||||
#include "FTP_Dir.hpp"
|
||||
#include "ftp.h"
|
||||
#include "net.h"
|
||||
|
||||
#define FTP_BUFFER_SIZE 1024
|
||||
#define MAX_CLIENTS 2
|
||||
|
||||
bool ftp_allow_active = false;
|
||||
u16 ftp_server_port = 21;
|
||||
|
||||
static const u16 SRC_PORT = 20;
|
||||
static const s32 EQUIT = 696969;
|
||||
static const char *CRLF = "\r\n";
|
||||
static const u32 CRLF_LENGTH = 2;
|
||||
|
||||
static u8 num_clients = 0;
|
||||
static u16 passive_port = 1024;
|
||||
static char *password = NULL;
|
||||
|
||||
typedef s32 (*data_connection_callback)(s32 data_socket, void *arg);
|
||||
|
||||
struct client_struct {
|
||||
s32 socket;
|
||||
char representation_type;
|
||||
s32 passive_socket;
|
||||
s32 data_socket;
|
||||
char cwd[MAXPATHLEN];
|
||||
char pending_rename[MAXPATHLEN];
|
||||
off_t restart_marker;
|
||||
struct sockaddr_in address;
|
||||
bool authenticated;
|
||||
char buf[FTP_BUFFER_SIZE];
|
||||
s32 offset;
|
||||
bool data_connection_connected;
|
||||
data_connection_callback data_callback;
|
||||
void *data_connection_callback_arg;
|
||||
void (*data_connection_cleanup)(void *arg);
|
||||
u64 data_connection_timer;
|
||||
};
|
||||
|
||||
typedef struct client_struct client_t;
|
||||
|
||||
static client_t *clients[MAX_CLIENTS] = { NULL };
|
||||
|
||||
void set_ftp_password(const char *new_password) {
|
||||
if (password != NULL) free(password);
|
||||
if (new_password != NULL && new_password[0] != '\0') {
|
||||
password = malloc(strlen(new_password) + 1);
|
||||
if (password == NULL) return;//die("Unable to allocate memory for password", errno);
|
||||
strcpy((char *)password, new_password);
|
||||
} else {
|
||||
password = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool compare_ftp_password(char *password_attempt) {
|
||||
return !password || !strcmp((char *)password, password_attempt);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: support multi-line reply
|
||||
*/
|
||||
static s32 write_reply(client_t *client, u16 code, char *msg) {
|
||||
u32 msglen = 4 + strlen(msg) + CRLF_LENGTH;
|
||||
char msgbuf[msglen + 1];
|
||||
if (msgbuf == NULL) return -ENOMEM;
|
||||
strncpy(msgbuf, fmt("%u %s\r\n", code, msg), msglen + 1);
|
||||
ftp_dbg_print(fmt("Wrote reply: %s", msgbuf));
|
||||
return send_exact(client->socket, msgbuf, msglen);
|
||||
}
|
||||
|
||||
static void close_passive_socket(client_t *client) {
|
||||
if (client->passive_socket >= 0) {
|
||||
net_close_blocking(client->passive_socket);
|
||||
client->passive_socket = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
result must be able to hold up to maxsplit+1 null-terminated strings of length strlen(s)
|
||||
returns the number of strings stored in the result array (up to maxsplit+1)
|
||||
*/
|
||||
static u32 split(char *s, char sep, u32 maxsplit, char *result[]) {
|
||||
u32 num_results = 0;
|
||||
u32 result_pos = 0;
|
||||
u32 trim_pos = 0;
|
||||
bool in_word = false;
|
||||
for (; *s; s++) {
|
||||
if (*s == sep) {
|
||||
if (num_results <= maxsplit) {
|
||||
in_word = false;
|
||||
continue;
|
||||
} else if (!trim_pos) {
|
||||
trim_pos = result_pos;
|
||||
}
|
||||
} else if (trim_pos) {
|
||||
trim_pos = 0;
|
||||
}
|
||||
if (!in_word) {
|
||||
in_word = true;
|
||||
if (num_results <= maxsplit) {
|
||||
num_results++;
|
||||
result_pos = 0;
|
||||
}
|
||||
}
|
||||
result[num_results - 1][result_pos++] = *s;
|
||||
result[num_results - 1][result_pos] = '\0';
|
||||
}
|
||||
if (trim_pos) {
|
||||
result[num_results - 1][trim_pos] = '\0';
|
||||
}
|
||||
u32 i = num_results;
|
||||
for (i = num_results; i <= maxsplit; i++) {
|
||||
result[i][0] = '\0';
|
||||
}
|
||||
return num_results;
|
||||
}
|
||||
|
||||
static s32 ftp_USER(client_t *client, char *username __attribute__((unused))) {
|
||||
return write_reply(client, 331, "User name okay, need password.");
|
||||
}
|
||||
|
||||
static s32 ftp_PASS(client_t *client, char *password_attempt) {
|
||||
if (compare_ftp_password(password_attempt)) {
|
||||
client->authenticated = true;
|
||||
return write_reply(client, 230, "User logged in, proceed.");
|
||||
} else {
|
||||
return write_reply(client, 530, "Login incorrect.");
|
||||
}
|
||||
}
|
||||
|
||||
static s32 ftp_REIN(client_t *client, char *rest __attribute__((unused))) {
|
||||
close_passive_socket(client);
|
||||
strcpy(client->cwd, "/");
|
||||
client->representation_type = 'A';
|
||||
client->authenticated = false;
|
||||
return write_reply(client, 220, "Service ready for new user.");
|
||||
}
|
||||
|
||||
static s32 ftp_QUIT(client_t *client, char *rest __attribute__((unused))) {
|
||||
// TODO: dont quit if xfer in progress
|
||||
s32 result = write_reply(client, 221, "Service closing control connection.");
|
||||
/* reset paths for some strange clients */
|
||||
ftp_init();
|
||||
return result < 0 ? result : -EQUIT;
|
||||
}
|
||||
|
||||
static s32 ftp_SYST(client_t *client, char *rest __attribute__((unused))) {
|
||||
return write_reply(client, 215, "UNIX Type: L8 Version: wiiflow-ftpii");
|
||||
}
|
||||
|
||||
static s32 ftp_TYPE(client_t *client, char *rest) {
|
||||
char representation_type[FTP_BUFFER_SIZE], param[FTP_BUFFER_SIZE];
|
||||
char *args[] = { representation_type, param };
|
||||
u32 num_args = split(rest, ' ', 1, args);
|
||||
if (num_args == 0) {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
} else if ((!strcasecmp("A", representation_type) && (!*param || !strcasecmp("N", param))) ||
|
||||
(!strcasecmp("I", representation_type) && num_args == 1)) {
|
||||
client->representation_type = *representation_type;
|
||||
} else {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
char msg[15];
|
||||
strncpy(msg, fmt("Type set to %s.", representation_type), 15);
|
||||
return write_reply(client, 200, msg);
|
||||
}
|
||||
|
||||
static s32 ftp_MODE(client_t *client, char *rest) {
|
||||
if (!strcasecmp("S", rest)) {
|
||||
return write_reply(client, 200, "Mode S ok.");
|
||||
} else {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
}
|
||||
|
||||
static s32 ftp_PWD(client_t *client, char *rest __attribute__((unused))) {
|
||||
char msg[MAXPATHLEN + 24];
|
||||
// TODO: escape double-quotes
|
||||
strncpy(msg, fmt("\"%s\" is current directory.", ftp_getpath()), MAXPATHLEN + 24);
|
||||
return write_reply(client, 257, msg);
|
||||
}
|
||||
|
||||
static s32 ftp_CWD(client_t *client, char *path) {
|
||||
s32 result;
|
||||
if (ftp_changedir(path) == 0) {
|
||||
result = write_reply(client, 250, "CWD command successful.");
|
||||
} else {
|
||||
result = write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_CDUP(client_t *client, char *rest __attribute__((unused))) {
|
||||
s32 result;
|
||||
if (ftp_changedir("..") == 0) {
|
||||
result = write_reply(client, 250, "CDUP command successful.");
|
||||
} else {
|
||||
result = write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_DELE(client_t *client, char *path) {
|
||||
if (ftp_delete(path) == 0) {
|
||||
return write_reply(client, 250, "File or directory removed.");
|
||||
} else {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static s32 ftp_MKD(client_t *client, char *path) {
|
||||
if (!*path) {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
if (ftp_makedir(path) == 0) {
|
||||
char msg[MAXPATHLEN + 21];
|
||||
// TODO: escape double-quotes
|
||||
strncpy(msg, fmt("\"%s\" directory created.", path), MAXPATHLEN + 21);
|
||||
return write_reply(client, 257, msg);
|
||||
} else {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static s32 ftp_RNFR(client_t *client, char *path) {
|
||||
strcpy(client->pending_rename, path);
|
||||
return write_reply(client, 350, "Ready for RNTO.");
|
||||
}
|
||||
|
||||
static s32 ftp_RNTO(client_t *client, char *path) {
|
||||
if (!*client->pending_rename) {
|
||||
return write_reply(client, 503, "RNFR required first.");
|
||||
}
|
||||
s32 result;
|
||||
if (ftp_rename(client->pending_rename, path) == 0) {
|
||||
result = write_reply(client, 250, "Rename successful.");
|
||||
} else {
|
||||
result = write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
*client->pending_rename = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_SIZE(client_t *client, char *path) {
|
||||
struct stat st;
|
||||
if (ftp_stat(path, &st) == 0) {
|
||||
char size_buf[12];
|
||||
strncpy(size_buf, fmt("%llu", st.st_size), 12);
|
||||
return write_reply(client, 213, size_buf);
|
||||
} else {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static s32 ftp_PASV(client_t *client, char *rest __attribute__((unused))) {
|
||||
close_passive_socket(client);
|
||||
client->passive_socket = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (client->passive_socket < 0) {
|
||||
return write_reply(client, 520, "Unable to create listening socket.");
|
||||
}
|
||||
set_blocking(client->passive_socket, false);
|
||||
struct sockaddr_in bindAddress;
|
||||
memset(&bindAddress, 0, sizeof(bindAddress));
|
||||
bindAddress.sin_family = AF_INET;
|
||||
if (passive_port < 1024) passive_port = 1024;
|
||||
bindAddress.sin_port = htons(passive_port++);
|
||||
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
s32 result;
|
||||
if ((result = net_bind(client->passive_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
|
||||
close_passive_socket(client);
|
||||
return write_reply(client, 520, "Unable to bind listening socket.");
|
||||
}
|
||||
if ((result = net_listen(client->passive_socket, 1)) < 0) {
|
||||
close_passive_socket(client);
|
||||
return write_reply(client, 520, "Unable to listen on socket.");
|
||||
}
|
||||
char reply[49];
|
||||
u16 port = bindAddress.sin_port;
|
||||
u32 ip = net_gethostip();
|
||||
struct in_addr addr;
|
||||
addr.s_addr = ip;
|
||||
ftp_dbg_print(fmt("Listening for data connections at %s:%u...\n", inet_ntoa(addr), port));
|
||||
strncpy(reply, fmt("Entering Passive Mode (%u,%u,%u,%u,%u,%u).", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, (port >> 8) & 0xff, port & 0xff), 49);
|
||||
return write_reply(client, 227, reply);
|
||||
}
|
||||
|
||||
static s32 ftp_PORT(client_t *client, char *portspec) {
|
||||
if(ftp_allow_active == false) /* port is only used for active clients */
|
||||
return write_reply(client, 502, "Command not implemented.");
|
||||
|
||||
u32 h1, h2, h3, h4, p1, p2;
|
||||
if (sscanf(portspec, "%3u,%3u,%3u,%3u,%3u,%3u", &h1, &h2, &h3, &h4, &p1, &p2) < 6) {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
char addr_str[44];
|
||||
strncpy(addr_str, fmt("%u.%u.%u.%u", h1, h2, h3, h4), 44);
|
||||
struct in_addr sin_addr;
|
||||
if (!inet_aton(addr_str, &sin_addr)) {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
close_passive_socket(client);
|
||||
u16 port = ((p1 &0xff) << 8) | (p2 & 0xff);
|
||||
client->address.sin_addr = sin_addr;
|
||||
client->address.sin_port = htons(port);
|
||||
ftp_dbg_print(fmt("Set client address to %s:%u\n", addr_str, port));
|
||||
return write_reply(client, 200, "PORT command successful.");
|
||||
}
|
||||
|
||||
typedef s32 (*data_connection_handler)(client_t *client);
|
||||
|
||||
static s32 prepare_data_connection_active(client_t *client) {
|
||||
s32 data_socket = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (data_socket < 0) return data_socket;
|
||||
set_blocking(data_socket, false);
|
||||
struct sockaddr_in bindAddress;
|
||||
memset(&bindAddress, 0, sizeof(bindAddress));
|
||||
bindAddress.sin_family = AF_INET;
|
||||
bindAddress.sin_port = htons(SRC_PORT);
|
||||
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
s32 result;
|
||||
if ((result = net_bind(data_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
|
||||
net_close(data_socket);
|
||||
return result;
|
||||
}
|
||||
|
||||
client->data_socket = data_socket;
|
||||
ftp_dbg_print(fmt("Attempting to connect to client at %s:%u\n",
|
||||
inet_ntoa(client->address.sin_addr), ntohs(client->address.sin_port)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 prepare_data_connection_passive(client_t *client) {
|
||||
client->data_socket = client->passive_socket;
|
||||
ftp_dbg_print("Waiting for data connections...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 prepare_data_connection(client_t *client, void *callback, void *arg, void *cleanup) {
|
||||
s32 result = write_reply(client, 150, "Transferring data.");
|
||||
if (result >= 0) {
|
||||
result = -1;
|
||||
if(client->passive_socket >= 0)
|
||||
result = prepare_data_connection_passive(client);
|
||||
else if(ftp_allow_active == true)
|
||||
result = prepare_data_connection_active(client);
|
||||
if (result < 0) {
|
||||
result = write_reply(client, 520, "Closing data connection, error occurred during transfer.");
|
||||
} else {
|
||||
client->data_connection_connected = false;
|
||||
client->data_callback = callback;
|
||||
client->data_connection_callback_arg = arg;
|
||||
client->data_connection_cleanup = cleanup;
|
||||
client->data_connection_timer = gettime() + secs_to_ticks(30);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 send_nlst(s32 data_socket, DIR *dir) {
|
||||
s32 result = 0;
|
||||
char filename[MAXPATHLEN + 2];
|
||||
while (ftp_dirnext(dir, filename) == 0) {
|
||||
size_t end_index = strlen(filename);
|
||||
filename[end_index] = CRLF[0];
|
||||
filename[end_index + 1] = CRLF[1];
|
||||
filename[end_index + 2] = '\0';
|
||||
if ((result = send_exact(data_socket, filename, strlen(filename))) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static s32 send_list(s32 data_socket, DIR *dir) {
|
||||
s32 result = 0;
|
||||
char filename[MAXPATHLEN];
|
||||
struct stat st;
|
||||
char line[MAXPATHLEN + 56 + CRLF_LENGTH + 1];
|
||||
while (ftp_dirnext(dir, filename) == 0) {
|
||||
char timestamp[13];
|
||||
ftp_stat(filename, &st);
|
||||
strftime(timestamp, sizeof(timestamp), "%b %d %Y", localtime(&st.st_mtime));
|
||||
strncpy(line, fmt("%crwxr-xr-x 1 0 0 %10llu %s %s\r\n", (st.st_mode & S_IFDIR) ? 'd' : '-', st.st_size, timestamp, filename), MAXPATHLEN + 56 + CRLF_LENGTH + 1);
|
||||
if ((result = send_exact(data_socket, line, strlen(line))) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static s32 ftp_NLST(client_t *client, char *path) {
|
||||
if (!*path) {
|
||||
path = ".";
|
||||
}
|
||||
|
||||
DIR *dir = ftp_diropen();
|
||||
if (dir == NULL) {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
|
||||
s32 result = prepare_data_connection(client, send_nlst, dir, ftp_dirclose);
|
||||
if (result < 0) ftp_dirclose(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_LIST(client_t *client, char *path) {
|
||||
if (*path == '-') {
|
||||
// handle buggy clients that use "LIST -aL" or similar, at the expense of breaking paths that begin with '-'
|
||||
char flags[FTP_BUFFER_SIZE];
|
||||
char rest[FTP_BUFFER_SIZE];
|
||||
char *args[] = { flags, rest };
|
||||
split(path, ' ', 1, args);
|
||||
path = rest;
|
||||
}
|
||||
if (!*path) {
|
||||
path = ".";
|
||||
}
|
||||
//s32 result = -1;
|
||||
DIR *dir = ftp_diropen();
|
||||
/*if (dir == NULL) {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}*/
|
||||
s32 result = prepare_data_connection(client, send_list, dir, ftp_dirclose);
|
||||
if (result < 0) ftp_dirclose(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_RETR(client_t *client, char *path) {
|
||||
FILE *f = ftp_fopen(path, "rb");
|
||||
if (!f) {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
|
||||
int fd = fileno(f);
|
||||
if (client->restart_marker && lseek(fd, client->restart_marker, SEEK_SET) != client->restart_marker) {
|
||||
s32 lseek_error = errno;
|
||||
ftp_fclose(f);
|
||||
client->restart_marker = 0;
|
||||
return write_reply(client, 550, strerror(lseek_error));
|
||||
}
|
||||
client->restart_marker = 0;
|
||||
|
||||
s32 result = prepare_data_connection(client, send_from_file, f, ftp_fclose);
|
||||
if (result < 0) ftp_fclose(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 stor_or_append(client_t *client, FILE *f) {
|
||||
if (!f) {
|
||||
return write_reply(client, 550, strerror(errno));
|
||||
}
|
||||
s32 result = prepare_data_connection(client, recv_to_file, f, ftp_fclose);
|
||||
if (result < 0) ftp_fclose(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
static s32 ftp_STOR(client_t *client, char *path __attribute__((unused))) {
|
||||
FILE *f = ftp_fopen(path, "wb");
|
||||
int fd;
|
||||
if (f) fd = fileno(f);
|
||||
if (f && client->restart_marker && lseek(fd, client->restart_marker, SEEK_SET) != client->restart_marker) {
|
||||
s32 lseek_error = errno;
|
||||
ftp_fclose(f);
|
||||
client->restart_marker = 0;
|
||||
return write_reply(client, 550, strerror(lseek_error));
|
||||
}
|
||||
client->restart_marker = 0;
|
||||
|
||||
return stor_or_append(client, f);
|
||||
}
|
||||
|
||||
static s32 ftp_APPE(client_t *client, char *path __attribute__((unused))) {
|
||||
return stor_or_append(client, ftp_fopen(path, "ab"));
|
||||
}
|
||||
|
||||
static s32 ftp_REST(client_t *client, char *offset_str) {
|
||||
off_t offset;
|
||||
if (sscanf(offset_str, "%lli", &offset) < 1 || offset < 0) {
|
||||
return write_reply(client, 501, "Syntax error in parameters.");
|
||||
}
|
||||
client->restart_marker = offset;
|
||||
char msg[FTP_BUFFER_SIZE];
|
||||
strncpy(msg, fmt("Restart position accepted (%lli).", offset), FTP_BUFFER_SIZE);
|
||||
return write_reply(client, 350, msg);
|
||||
}
|
||||
|
||||
typedef s32 (*ftp_command_handler)(client_t *client, char *args);
|
||||
|
||||
static s32 dispatch_to_handler(client_t *client, char *cmd_line, const char **commands, const ftp_command_handler *handlers) {
|
||||
char cmd[FTP_BUFFER_SIZE], rest[FTP_BUFFER_SIZE];
|
||||
char *args[] = { cmd, rest };
|
||||
split(cmd_line, ' ', 1, args);
|
||||
s32 i;
|
||||
for (i = 0; commands[i]; i++) {
|
||||
if (!strcasecmp(commands[i], cmd)) break;
|
||||
}
|
||||
return handlers[i](client, rest);
|
||||
}
|
||||
|
||||
static s32 ftp_NOOP(client_t *client, char *rest __attribute__((unused))) {
|
||||
return write_reply(client, 200, "NOOP command successful.");
|
||||
}
|
||||
|
||||
static s32 ftp_SUPERFLUOUS(client_t *client, char *rest __attribute__((unused))) {
|
||||
return write_reply(client, 202, "Command not implemented, superfluous at this site.");
|
||||
}
|
||||
|
||||
static s32 ftp_NEEDAUTH(client_t *client, char *rest __attribute__((unused))) {
|
||||
return write_reply(client, 530, "Please login with USER and PASS.");
|
||||
}
|
||||
|
||||
static s32 ftp_UNKNOWN(client_t *client, char *rest __attribute__((unused))) {
|
||||
return write_reply(client, 502, "Command not implemented.");
|
||||
}
|
||||
|
||||
static const char *unauthenticated_commands[] = { "USER", "PASS", "QUIT", "REIN", "NOOP", NULL };
|
||||
static const ftp_command_handler unauthenticated_handlers[] = { ftp_USER, ftp_PASS, ftp_QUIT, ftp_REIN, ftp_NOOP, ftp_NEEDAUTH };
|
||||
|
||||
static const char *authenticated_commands[] = {
|
||||
"USER", "PASS", "LIST", "PWD", "CWD", "CDUP",
|
||||
"SIZE", "PASV", "PORT", "TYPE", "SYST", "MODE",
|
||||
"RETR", "STOR", "APPE", "REST", "DELE", "MKD",
|
||||
"RMD", "RNFR", "RNTO", "NLST", "QUIT", "REIN",
|
||||
"NOOP", "ALLO", NULL
|
||||
};
|
||||
static const ftp_command_handler authenticated_handlers[] = {
|
||||
ftp_USER, ftp_PASS, ftp_LIST, ftp_PWD, ftp_CWD, ftp_CDUP,
|
||||
ftp_SIZE, ftp_PASV, ftp_PORT, ftp_TYPE, ftp_SYST, ftp_MODE,
|
||||
ftp_RETR, ftp_STOR, ftp_APPE, ftp_REST, ftp_DELE, ftp_MKD,
|
||||
ftp_DELE, ftp_RNFR, ftp_RNTO, ftp_NLST, ftp_QUIT, ftp_REIN,
|
||||
ftp_NOOP, ftp_SUPERFLUOUS, ftp_UNKNOWN
|
||||
};
|
||||
|
||||
/*
|
||||
returns negative to signal an error that requires closing the connection
|
||||
*/
|
||||
static s32 process_command(client_t *client, char *cmd_line) {
|
||||
if (strlen(cmd_line) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ftp_dbg_print(fmt("Got command: %s\n", cmd_line));
|
||||
|
||||
const char **commands = unauthenticated_commands;
|
||||
const ftp_command_handler *handlers = unauthenticated_handlers;
|
||||
|
||||
if (client->authenticated) {
|
||||
commands = authenticated_commands;
|
||||
handlers = authenticated_handlers;
|
||||
}
|
||||
|
||||
return dispatch_to_handler(client, cmd_line, commands, handlers);
|
||||
}
|
||||
|
||||
static void cleanup_data_resources(client_t *client) {
|
||||
if (client->data_socket >= 0 && client->data_socket != client->passive_socket) {
|
||||
net_close_blocking(client->data_socket);
|
||||
}
|
||||
client->data_socket = -1;
|
||||
client->data_connection_connected = false;
|
||||
client->data_callback = NULL;
|
||||
if (client->data_connection_cleanup) {
|
||||
client->data_connection_cleanup(client->data_connection_callback_arg);
|
||||
}
|
||||
client->data_connection_callback_arg = NULL;
|
||||
client->data_connection_cleanup = NULL;
|
||||
client->data_connection_timer = 0;
|
||||
}
|
||||
|
||||
static void cleanup_client(client_t *client) {
|
||||
net_close_blocking(client->socket);
|
||||
cleanup_data_resources(client);
|
||||
close_passive_socket(client);
|
||||
int client_index;
|
||||
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
|
||||
if (clients[client_index] == client) {
|
||||
clients[client_index] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(client);
|
||||
num_clients--;
|
||||
if(num_clients == 0)
|
||||
ftp_init(); /* reinit for new clients */
|
||||
ftp_dbg_print("Client disconnected.\n");
|
||||
}
|
||||
|
||||
void cleanup_ftp() {
|
||||
int client_index;
|
||||
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
|
||||
client_t *client = clients[client_index];
|
||||
if (client) {
|
||||
write_reply(client, 421, "Service not available, closing control connection.");
|
||||
cleanup_client(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool process_accept_events(s32 server) {
|
||||
s32 peer;
|
||||
struct sockaddr_in client_address;
|
||||
socklen_t addrlen = sizeof(client_address);
|
||||
while ((peer = net_accept(server, (struct sockaddr *)&client_address, &addrlen)) != -EAGAIN) {
|
||||
if (peer < 0) {
|
||||
ftp_dbg_print(fmt("Error accepting connection: [%i] %s\n", -peer, strerror(-peer)));
|
||||
return false;
|
||||
}
|
||||
|
||||
ftp_dbg_print(fmt("Accepted connection from %s!\n", inet_ntoa(client_address.sin_addr)));
|
||||
|
||||
if (num_clients == MAX_CLIENTS) {
|
||||
ftp_dbg_print(fmt("Maximum of %u clients reached, not accepting client.\n", MAX_CLIENTS));
|
||||
net_close(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
client_t *client = malloc(sizeof(client_t));
|
||||
if (!client) {
|
||||
ftp_dbg_print("Could not allocate memory for client state, not accepting client.\n");
|
||||
net_close(peer);
|
||||
return true;
|
||||
}
|
||||
client->socket = peer;
|
||||
client->representation_type = 'A';
|
||||
client->passive_socket = -1;
|
||||
client->data_socket = -1;
|
||||
strcpy(client->cwd, "/");
|
||||
*client->pending_rename = '\0';
|
||||
client->restart_marker = 0;
|
||||
client->authenticated = false;
|
||||
client->offset = 0;
|
||||
client->data_connection_connected = false;
|
||||
client->data_callback = NULL;
|
||||
client->data_connection_callback_arg = NULL;
|
||||
client->data_connection_cleanup = NULL;
|
||||
client->data_connection_timer = 0;
|
||||
memcpy(&client->address, &client_address, sizeof(client_address));
|
||||
int client_index;
|
||||
char *welcome = fmt("Welcome to %s (%s-r%s)! This is the ftpii server core.", APP_NAME, APP_VERSION, SVN_REV);
|
||||
if (write_reply(client, 220, welcome) < 0) {
|
||||
ftp_dbg_print("Error writing greeting.\n");
|
||||
net_close_blocking(peer);
|
||||
free(client);
|
||||
} else {
|
||||
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
|
||||
if (!clients[client_index]) {
|
||||
clients[client_index] = client;
|
||||
break;
|
||||
}
|
||||
}
|
||||
num_clients++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void process_data_events(client_t *client) {
|
||||
s32 result = -1;
|
||||
if (!client->data_connection_connected) {
|
||||
if (client->passive_socket >= 0) {
|
||||
struct sockaddr_in data_peer_address;
|
||||
socklen_t addrlen = sizeof(data_peer_address);
|
||||
result = net_accept(client->passive_socket, (struct sockaddr *)&data_peer_address ,&addrlen);
|
||||
if (result >= 0) {
|
||||
client->data_socket = result;
|
||||
client->data_connection_connected = true;
|
||||
}
|
||||
} else if(ftp_allow_active == true) {
|
||||
if ((result = net_connect(client->data_socket, (struct sockaddr *)&client->address, sizeof(client->address))) < 0) {
|
||||
if(result == -EINPROGRESS || result == -EALREADY)
|
||||
result = -EAGAIN;
|
||||
if(result != -EAGAIN && result != -EISCONN)
|
||||
ftp_dbg_print(fmt("Unable to connect to client: [%i] %s\n", -result, strerror(-result)));
|
||||
}
|
||||
if (result >= 0 || result == -EISCONN) {
|
||||
client->data_connection_connected = true;
|
||||
}
|
||||
}
|
||||
if (client->data_connection_connected) {
|
||||
result = 1;
|
||||
ftp_dbg_print("Connected to client! Transferring data...\n");
|
||||
} else if (gettime() > client->data_connection_timer) {
|
||||
result = -1;
|
||||
ftp_dbg_print("Timed out waiting for data connection.\n");
|
||||
}
|
||||
} else {
|
||||
result = client->data_callback(client->data_socket, client->data_connection_callback_arg);
|
||||
}
|
||||
|
||||
if (result <= 0 && result != -EAGAIN) {
|
||||
cleanup_data_resources(client);
|
||||
if (result < 0) {
|
||||
result = write_reply(client, 520, "Closing data connection, error occurred during transfer.");
|
||||
} else {
|
||||
result = write_reply(client, 226, "Closing data connection, transfer successful.");
|
||||
}
|
||||
if (result < 0) {
|
||||
cleanup_client(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void process_control_events(client_t *client) {
|
||||
s32 bytes_read;
|
||||
while (client->offset < (FTP_BUFFER_SIZE - 1)) {
|
||||
if (client->data_callback) {
|
||||
return;
|
||||
}
|
||||
char *offset_buf = client->buf + client->offset;
|
||||
if ((bytes_read = net_read(client->socket, offset_buf, FTP_BUFFER_SIZE - 1 - client->offset)) < 0) {
|
||||
if (bytes_read != -EAGAIN) {
|
||||
ftp_dbg_print(fmt("Read error %i occurred, closing client.\n", bytes_read));
|
||||
goto recv_loop_end;
|
||||
}
|
||||
return;
|
||||
} else if (bytes_read == 0) {
|
||||
goto recv_loop_end; // EOF from client
|
||||
}
|
||||
client->offset += bytes_read;
|
||||
client->buf[client->offset] = '\0';
|
||||
|
||||
if (strchr(offset_buf, '\0') != (client->buf + client->offset)) {
|
||||
ftp_dbg_print("Received a null byte from client, closing connection ;-)\n"); // i have decided this isn't allowed =P
|
||||
goto recv_loop_end;
|
||||
}
|
||||
|
||||
char *next;
|
||||
char *end;
|
||||
for (next = client->buf; (end = strstr(next, CRLF)) && !client->data_callback; next = end + CRLF_LENGTH) {
|
||||
*end = '\0';
|
||||
if (strchr(next, '\n')) {
|
||||
ftp_dbg_print("Received a line-feed from client without preceding carriage return, closing connection ;-)\n"); // i have decided this isn't allowed =P
|
||||
goto recv_loop_end;
|
||||
}
|
||||
|
||||
if (*next) {
|
||||
s32 result;
|
||||
if ((result = process_command(client, next)) < 0) {
|
||||
if (result != -EQUIT) {
|
||||
ftp_dbg_print(fmt("Closing connection due to error while processing command: %s\n", next));
|
||||
}
|
||||
goto recv_loop_end;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (next != client->buf) { // some lines were processed
|
||||
client->offset = strlen(next);
|
||||
char tmp_buf[client->offset];
|
||||
memcpy(tmp_buf, next, client->offset);
|
||||
memcpy(client->buf, tmp_buf, client->offset);
|
||||
}
|
||||
}
|
||||
ftp_dbg_print(fmt("Received line longer than %u bytes, closing client.\n", FTP_BUFFER_SIZE - 1));
|
||||
|
||||
recv_loop_end:
|
||||
cleanup_client(client);
|
||||
}
|
||||
|
||||
bool process_ftp_events(s32 server) {
|
||||
bool network_down = !process_accept_events(server);
|
||||
int client_index;
|
||||
for (client_index = 0; client_index < MAX_CLIENTS; client_index++) {
|
||||
client_t *client = clients[client_index];
|
||||
if (client) {
|
||||
if (client->data_callback) {
|
||||
process_data_events(client);
|
||||
} else {
|
||||
process_control_events(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
return network_down;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
#ifndef _FTP_H_
|
||||
#define _FTP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void accept_ftp_client(s32 server);
|
||||
void set_ftp_password(const char *new_password);
|
||||
bool process_ftp_events(s32 server);
|
||||
void cleanup_ftp();
|
||||
|
||||
extern bool ftp_allow_active;
|
||||
extern u16 ftp_server_port;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _FTP_H_ */
|
@ -1,155 +0,0 @@
|
||||
// Copyright 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
#include <errno.h>
|
||||
#include <gccore.h>
|
||||
#include <network.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#include "net.h"
|
||||
#include "ftp.h"
|
||||
#include "FTP_Dir.hpp"
|
||||
#include "loader/sys.h"
|
||||
#include "gecko/gecko.hpp"
|
||||
|
||||
#define MAX_NET_BUFFER_SIZE 32768
|
||||
#define MIN_NET_BUFFER_SIZE 4096
|
||||
#define FREAD_BUFFER_SIZE 32768
|
||||
|
||||
static u32 NET_BUFFER_SIZE = MAX_NET_BUFFER_SIZE;
|
||||
s32 ftp_server = -1;
|
||||
|
||||
s32 set_blocking(s32 s, bool blocking) {
|
||||
s32 flags;
|
||||
flags = net_fcntl(s, F_GETFL, 0);
|
||||
if (flags >= 0) flags = net_fcntl(s, F_SETFL, blocking ? (flags&~4) : (flags|4));
|
||||
return flags;
|
||||
}
|
||||
|
||||
s32 net_close_blocking(s32 s) {
|
||||
set_blocking(s, true);
|
||||
return net_close(s);
|
||||
}
|
||||
|
||||
bool create_server(void) {
|
||||
ftp_init();
|
||||
ftp_server = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (ftp_server < 0) return false;
|
||||
set_blocking(ftp_server, false);
|
||||
|
||||
struct sockaddr_in bindAddress;
|
||||
memset(&bindAddress, 0, sizeof(bindAddress));
|
||||
bindAddress.sin_family = AF_INET;
|
||||
bindAddress.sin_port = htons(ftp_server_port);
|
||||
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
s32 ret;
|
||||
if ((ret = net_bind(ftp_server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
|
||||
net_close(ftp_server);
|
||||
ftp_server = -1;
|
||||
gprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret));
|
||||
return false;
|
||||
}
|
||||
if ((ret = net_listen(ftp_server, 3)) < 0) {
|
||||
net_close(ftp_server);
|
||||
ftp_server = -1;
|
||||
gprintf("Error listening on socket: [%i] %s\n", -ret, strerror(-ret));
|
||||
return false;
|
||||
}
|
||||
gprintf("FTP Server started\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void end_server(void)
|
||||
{
|
||||
if(ftp_server < 0)
|
||||
return;
|
||||
cleanup_ftp();
|
||||
net_close(ftp_server);
|
||||
ftp_server = -1;
|
||||
gprintf("FTP Server ended\n");
|
||||
}
|
||||
|
||||
s32 get_server_num(void)
|
||||
{
|
||||
return ftp_server;
|
||||
}
|
||||
|
||||
typedef s32 (*transferrer_type)(s32 s, void *mem, s32 len);
|
||||
static s32 transfer_exact(s32 s, char *buf, s32 length, transferrer_type transferrer) {
|
||||
s32 result = 0;
|
||||
s32 remaining = length;
|
||||
s32 bytes_transferred;
|
||||
set_blocking(s, true);
|
||||
while (remaining) {
|
||||
try_again_with_smaller_buffer:
|
||||
bytes_transferred = transferrer(s, buf, MIN(remaining, (int)NET_BUFFER_SIZE));
|
||||
if (bytes_transferred > 0) {
|
||||
remaining -= bytes_transferred;
|
||||
buf += bytes_transferred;
|
||||
} else if (bytes_transferred < 0) {
|
||||
if (bytes_transferred == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) {
|
||||
NET_BUFFER_SIZE = MIN_NET_BUFFER_SIZE;
|
||||
goto try_again_with_smaller_buffer;
|
||||
}
|
||||
result = bytes_transferred;
|
||||
break;
|
||||
} else {
|
||||
result = -ENODATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
set_blocking(s, false);
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 send_exact(s32 s, char *buf, s32 length) {
|
||||
return transfer_exact(s, buf, length, (transferrer_type)net_write);
|
||||
}
|
||||
|
||||
s32 send_from_file(s32 s, FILE *f) {
|
||||
char buf[FREAD_BUFFER_SIZE];
|
||||
s32 bytes_read;
|
||||
s32 result = 0;
|
||||
|
||||
DCFlushRange(buf, FREAD_BUFFER_SIZE);
|
||||
ICInvalidateRange(buf, FREAD_BUFFER_SIZE);
|
||||
bytes_read = fread(buf, 1, FREAD_BUFFER_SIZE, f);
|
||||
if (bytes_read > 0) {
|
||||
DCFlushRange(buf, bytes_read);
|
||||
result = send_exact(s, buf, bytes_read);
|
||||
if (result < 0) goto end;
|
||||
}
|
||||
if (bytes_read < FREAD_BUFFER_SIZE) {
|
||||
result = -!feof(f);
|
||||
goto end;
|
||||
}
|
||||
return -EAGAIN;
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 recv_to_file(s32 s, FILE *f) {
|
||||
char buf[NET_BUFFER_SIZE];
|
||||
s32 bytes_read;
|
||||
while (1) {
|
||||
try_again_with_smaller_buffer:
|
||||
DCFlushRange(buf, NET_BUFFER_SIZE);
|
||||
ICInvalidateRange(buf, NET_BUFFER_SIZE);
|
||||
bytes_read = net_read(s, buf, NET_BUFFER_SIZE);
|
||||
if (bytes_read < 0) {
|
||||
if (bytes_read == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) {
|
||||
NET_BUFFER_SIZE = MIN_NET_BUFFER_SIZE;
|
||||
goto try_again_with_smaller_buffer;
|
||||
}
|
||||
return bytes_read;
|
||||
} else if (bytes_read == 0) {
|
||||
return 0;
|
||||
}
|
||||
DCFlushRange(buf, bytes_read);
|
||||
s32 bytes_written = fwrite(buf, 1, bytes_read, f);
|
||||
if (bytes_written < bytes_read) return -1;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2010 Joseph Jordan <joe.ftpii@psychlaw.com.au>
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2;
|
||||
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
#ifndef _NET_H_
|
||||
#define _NET_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void initialise_network();
|
||||
s32 set_blocking(s32 s, bool blocking);
|
||||
s32 net_close_blocking(s32 s);
|
||||
bool create_server(void);
|
||||
s32 get_server_num(void);
|
||||
void end_server(void);
|
||||
s32 send_exact(s32 s, char *buf, s32 length);
|
||||
s32 send_from_file(s32 s, FILE *f);
|
||||
s32 recv_to_file(s32 s, FILE *f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _NET_H_ */
|
@ -67,6 +67,7 @@ bool Plugin::AddPlugin(Config &plugin)
|
||||
NewPlugin.coverFolder = plugin.getString(PLUGIN, "coverFolder");
|
||||
NewPlugin.magic = strtoul(plugin.getString(PLUGIN, "magic").c_str(), NULL, 16);
|
||||
NewPlugin.caseColor = strtoul(plugin.getString(PLUGIN, "coverColor").c_str(), NULL, 16);
|
||||
NewPlugin.romPartition = plugin.getInt(PLUGIN, "rompartition", -1);
|
||||
NewPlugin.romDir = plugin.getString(PLUGIN, "romDir");
|
||||
NewPlugin.fileTypes = plugin.getString(PLUGIN, "fileTypes");
|
||||
NewPlugin.Args = plugin.getStrings(PLUGIN, "arguments", '|');
|
||||
@ -134,6 +135,11 @@ const char *Plugin::GetCoverFolderName(u32 magic)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int Plugin::GetRomPartition(u8 pos)
|
||||
{
|
||||
return Plugins[pos].romPartition;
|
||||
}
|
||||
|
||||
const char *Plugin::GetRomDir(u8 pos)
|
||||
{
|
||||
return Plugins[pos].romDir.c_str();
|
||||
|
@ -43,6 +43,7 @@ struct PluginOptions
|
||||
{
|
||||
u32 magic;
|
||||
u32 caseColor;
|
||||
int romPartition;
|
||||
string romDir;
|
||||
string fileTypes;
|
||||
string DolName;
|
||||
@ -63,6 +64,7 @@ public:
|
||||
const char *GetDolName(u32 magic);
|
||||
const char *GetCoverFolderName(u32 magic);
|
||||
const char *GetRomDir(u8 pos);
|
||||
int GetRomPartition(u8 pos);
|
||||
const string& GetFileTypes(u8 pos);
|
||||
wstringEx GetPluginName(u8 pos);
|
||||
u32 getPluginMagic(u8 pos);
|
||||
|
@ -144,13 +144,13 @@ cfgne28=Game Save Flasher
|
||||
cfgne29=Flashed: %d saves / %d files / %d folders
|
||||
cfgne30=Flashing save files finished!
|
||||
cfgne31=Select Partition
|
||||
cfgne32=Change Nand
|
||||
cfgne33=Change Saves Nand
|
||||
cfgne32=Select Saves NAND
|
||||
cfgne33=Saves NAND Emulation
|
||||
cfgne34=Set
|
||||
cfgne35=Back
|
||||
cfgne36=Path =
|
||||
cfgne37=Select Preset Nand
|
||||
cfgne38=Empty
|
||||
cfgne37=Select NAND
|
||||
cfgne38=Saves NAND Partition
|
||||
cfgp1=Game Partition
|
||||
cfgp2=Flat Covers
|
||||
cfgp3=Init network on boot
|
||||
@ -255,6 +255,7 @@ errgame9=This is not a Wii or GC disc
|
||||
errgame10=Set USB failed: %d
|
||||
errgame11=GameCube Loader not found! Can't launch game.
|
||||
errgame12=Nintendont not found! Can't launch GC Disc.
|
||||
errgame13=EmuNAND for gamesave not found! Using real NAND.
|
||||
errneek1=Cannot launch neek2o. Verify your neek2o setup
|
||||
exit_to=Exit To
|
||||
ftp1=Start
|
||||
@ -306,10 +307,12 @@ lngspa=Spanish
|
||||
lngsys=System
|
||||
lngtch=T. Chinese
|
||||
main1=Install Game
|
||||
main2=Welcome to WiiFlow. I have not found any games. Click Install to install games, or Select partition to select your partition type.
|
||||
main3=Select Partition
|
||||
main4=Welcome to WiiFlow. I have not found any homebrew apps. Select partition to select your partition type.
|
||||
main5=Welcome to WiiFlow. I have not found any plugins. Select partition to select your partition type.
|
||||
main2=No games found in
|
||||
main3=No titles found in
|
||||
main4=No apps found in
|
||||
main5=No roms/items found.
|
||||
main6=No plugins Selected.
|
||||
main7=Total Games: %u
|
||||
mastersystem=Sega Master System
|
||||
menu=System Menu
|
||||
NANDfull=Full
|
||||
|
Loading…
Reference in New Issue
Block a user