2012-10-03 23:34:37 +02:00
# include <dirent.h>
# include <unistd.h>
2012-05-03 01:08:11 +02:00
# include "menu.hpp"
# include "defines.h"
2012-08-05 15:48:15 +02:00
# include "lockMutex.hpp"
# include "channel/nand.hpp"
# include "fileOps/fileOps.h"
# include "loader/cios.h"
2012-08-11 14:27:38 +02:00
# include "loader/nk.h"
2012-05-03 01:08:11 +02:00
2012-06-08 15:05:21 +02:00
// NandEmulation menu
2012-09-13 16:54:17 +02:00
s16 m_nandemuLblTitle ;
s16 m_nandemuBtnBack ;
s16 m_nandemuLblEmulationVal ;
s16 m_nandemuLblEmulation ;
s16 m_nandemuBtnEmulationM ;
s16 m_nandemuBtnEmulationP ;
s16 m_nandemuLblSaveDump ;
s16 m_nandemuBtnAll ;
s16 m_nandemuBtnMissing ;
s16 m_nandemuLblNandDump ;
s16 m_nandemuBtnNandDump ;
s16 m_nandfileLblMessage ;
s16 m_nandemuLblMessage ;
s16 m_nandfileLblDialog ;
s16 m_nandfinLblDialog ;
s16 m_nandemuLblDialog ;
s16 m_nandfilePBar ;
s16 m_nandemuPBar ;
s16 m_nandemuBtnExtract ;
s16 m_nandemuBtnDisable ;
s16 m_nandemuBtnPartition ;
s16 m_nandemuLblInit ;
s16 m_nandemuLblUser [ 4 ] ;
2012-06-08 15:05:21 +02:00
STexture m_nandemuBg ;
bool m_nandext ;
bool m_fulldump ;
bool m_sgdump ;
bool m_saveall ;
2012-05-03 01:08:11 +02:00
static inline int loopNum ( int i , int s )
{
return i < 0 ? ( s - ( - i % s ) ) % s : i % s ;
}
2012-06-07 02:34:47 +02:00
static bool _saveExists ( const char * path )
{
DIR * d ;
d = opendir ( path ) ;
if ( ! d )
{
return false ;
}
else
{
closedir ( d ) ;
return true ;
}
}
bool CMenu : : _TestEmuNand ( int epart , const char * path , bool indept )
{
char basepath [ 64 ] ;
char testpath [ MAX_FAT_PATH ] ;
snprintf ( basepath , sizeof ( basepath ) , " %s:%s " , DeviceName [ epart ] , path ) ;
2012-09-10 00:38:42 +02:00
2012-06-07 02:34:47 +02:00
DIR * d ;
d = opendir ( basepath ) ;
if ( ! d )
2012-09-10 00:38:42 +02:00
return false ;
2012-06-07 02:34:47 +02:00
else
closedir ( d ) ;
if ( indept )
{
// Check Wiimotes && Region
snprintf ( testpath , sizeof ( testpath ) , " %s:%s/shared2/sys/SYSCONF " , DeviceName [ epart ] , path ) ;
2012-06-07 07:14:51 +02:00
if ( ! fsop_FileExist ( testpath ) )
2012-09-10 00:38:42 +02:00
return false ;
2012-06-07 02:34:47 +02:00
snprintf ( testpath , sizeof ( testpath ) , " %s:%s/title/00000001/00000002/data/setting.txt " , DeviceName [ epart ] , path ) ;
2012-06-07 07:14:51 +02:00
if ( ! fsop_FileExist ( testpath ) )
2012-09-10 00:38:42 +02:00
return false ;
2012-06-07 02:34:47 +02:00
// Check Mii's
snprintf ( testpath , sizeof ( testpath ) , " %s:%s/shared2/menu/FaceLib/RFL_DB.dat " , DeviceName [ epart ] , path ) ;
2012-06-07 07:14:51 +02:00
if ( ! fsop_FileExist ( testpath ) )
2012-09-10 00:38:42 +02:00
return false ;
2012-06-07 02:34:47 +02:00
}
2012-09-10 00:38:42 +02:00
return true ;
2012-06-07 02:34:47 +02:00
}
int CMenu : : _FindEmuPart ( string * emuPath , int part , bool searchvalid )
{
2012-10-15 21:16:14 +02:00
NandHandle . Disable_Emu ( ) ;
2012-09-10 00:38:42 +02:00
2012-06-07 02:34:47 +02:00
int emuPartition = - 1 ;
string tmpPath ;
if ( m_current_view = = COVERFLOW_CHANNEL )
{
2012-11-04 20:22:02 +01:00
emuPartition = m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , 0 ) ;
tmpPath = m_cfg . getString ( CHANNEL_DOMAIN , " path " , " " ) ;
2012-06-07 02:34:47 +02:00
if ( tmpPath . size ( ) = = 0 )
{
2012-11-04 20:22:02 +01:00
m_cfg . setString ( CHANNEL_DOMAIN , " path " , STDEMU_DIR ) ;
tmpPath = m_cfg . getString ( CHANNEL_DOMAIN , " path " , STDEMU_DIR ) ;
2012-06-07 02:34:47 +02:00
}
}
else if ( m_current_view = = COVERFLOW_USB )
{
2012-11-04 20:22:02 +01:00
emuPartition = m_cfg . getInt ( WII_DOMAIN , " savepartition " , - 1 ) ;
2012-06-07 02:34:47 +02:00
if ( emuPartition = = - 1 )
2012-11-04 20:22:02 +01:00
emuPartition = m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , 0 ) ;
tmpPath = m_cfg . getString ( WII_DOMAIN , " savepath " , m_cfg . getString ( CHANNEL_DOMAIN , " path " , " " ) ) ;
2012-06-07 02:34:47 +02:00
if ( tmpPath . size ( ) = = 0 )
{
2012-11-04 20:22:02 +01:00
m_cfg . setString ( WII_DOMAIN , " savepath " , STDEMU_DIR ) ;
tmpPath = m_cfg . getString ( WII_DOMAIN , " savepath " , STDEMU_DIR ) ;
2012-06-07 02:34:47 +02:00
}
}
2012-09-10 00:38:42 +02:00
2012-09-22 15:47:52 +02:00
if ( ! DeviceHandle . IsInserted ( emuPartition ) )
DeviceHandle . Mount ( emuPartition ) ;
2012-09-10 00:38:42 +02:00
2012-09-22 15:47:52 +02:00
if ( _TestEmuNand ( emuPartition , tmpPath . c_str ( ) , true ) & & DeviceHandle . PartitionUsableForNandEmu ( emuPartition ) )
2012-08-26 17:20:51 +02:00
{
2012-06-07 02:34:47 +02:00
* emuPath = tmpPath ;
return emuPartition ;
2012-08-26 17:20:51 +02:00
}
2012-06-07 02:34:47 +02:00
else
2012-08-26 17:20:51 +02:00
{
2012-06-07 02:34:47 +02:00
bool fllscn = emuPartition = = - 1 ;
2012-09-10 00:38:42 +02:00
for ( u8 i = part ; i < = USB8 ; + + i )
2012-06-07 02:34:47 +02:00
{
2012-09-22 15:47:52 +02:00
if ( ! DeviceHandle . IsInserted ( i ) )
DeviceHandle . Mount ( i ) ;
2012-09-10 00:38:42 +02:00
2012-09-22 15:47:52 +02:00
if ( ! DeviceHandle . PartitionUsableForNandEmu ( i ) )
2012-06-07 02:34:47 +02:00
continue ;
2012-09-10 00:38:42 +02:00
if ( _TestEmuNand ( i , tmpPath . c_str ( ) , true ) | | searchvalid )
2012-06-07 02:34:47 +02:00
{
2012-09-10 00:38:42 +02:00
if ( m_current_view = = COVERFLOW_CHANNEL )
2012-11-04 20:22:02 +01:00
m_cfg . setInt ( CHANNEL_DOMAIN , " partition " , i ) ;
2012-09-10 00:38:42 +02:00
else if ( m_current_view = = COVERFLOW_USB )
2012-11-04 20:22:02 +01:00
m_cfg . setInt ( WII_DOMAIN , " savepartition " , i ) ;
2012-06-07 02:34:47 +02:00
2012-09-10 00:38:42 +02:00
* emuPath = tmpPath ;
m_cfg . save ( ) ;
2012-06-07 02:34:47 +02:00
2012-09-10 00:38:42 +02:00
return i ;
2012-06-07 02:34:47 +02:00
}
if ( i = = USB8 & & ! fllscn )
{
2012-09-10 00:38:42 +02:00
i = - 1 ;
2012-06-07 02:34:47 +02:00
fllscn = true ;
}
}
}
return - 1 ;
}
2012-05-11 01:38:34 +02:00
bool CMenu : : _checkSave ( string id , bool nand )
{
int savePath = id . c_str ( ) [ 0 ] < < 24 | id . c_str ( ) [ 1 ] < < 16 | id . c_str ( ) [ 2 ] < < 8 | id . c_str ( ) [ 3 ] ;
if ( nand )
{
u32 temp = 0 ;
2012-11-18 14:40:26 +01:00
if ( ISFS_ReadDir ( fmt ( " /title/00010000/%08x " , savePath ) , NULL , & temp ) < 0 )
if ( ISFS_ReadDir ( fmt ( " /title/00010004/%08x " , savePath ) , NULL , & temp ) < 0 )
2012-05-11 01:38:34 +02:00
return false ;
}
else
{
2012-11-04 20:22:02 +01:00
int emuPartition = m_cfg . getInt ( WII_DOMAIN , " savepartition " , - 1 ) ;
string emuPath = m_cfg . getString ( WII_DOMAIN , " savepath " , " " ) ;
2012-05-11 01:38:34 +02:00
if ( emuPartition < 0 | | emuPath . size ( ) = = 0 )
return false ;
struct stat fstat ;
2012-11-18 14:40:26 +01:00
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 ) )
2012-05-11 01:38:34 +02:00
return false ;
}
return true ;
}
2012-05-03 01:08:11 +02:00
void CMenu : : _setDumpMsg ( const wstringEx & msg , float totprog , float fileprog )
{
if ( m_thrdStop ) return ;
if ( msg ! = L " ... " ) m_thrdMessage = msg ;
m_thrdMessageAdded = true ;
m_thrdProgress = totprog ;
m_fileProgress = fileprog ;
}
void CMenu : : _ShowProgress ( int dumpstat , int dumpprog , int filesize , int fileprog , int files , int folders , char * tmess , void * user_data )
{
CMenu & m = * ( CMenu * ) user_data ;
m . m_progress = dumpprog = = 0 ? 0.f : ( float ) dumpstat / ( float ) dumpprog ;
m . m_fprogress = filesize = = 0 ? 0.f : ( float ) fileprog / ( float ) filesize ;
m . m_fileprog = fileprog ;
m . m_filesize = filesize ;
m . m_filesdone = files ;
m . m_foldersdone = folders ;
LWP_MutexLock ( m . m_mutex ) ;
2012-06-08 15:05:21 +02:00
if ( m_nandext )
2012-05-03 01:08:11 +02:00
m . _setDumpMsg ( wfmt ( m . _fmt ( " cfgne9 " , L " Current file: %s " ) , tmess ) , m . m_progress , m . m_fprogress ) ;
else
m . _setDumpMsg ( L " ... " , m . m_progress , m . m_fprogress ) ;
LWP_MutexUnlock ( m . m_mutex ) ;
}
void CMenu : : _hideNandEmu ( bool instant )
{
m_btnMgr . hide ( m_nandemuLblTitle , instant ) ;
m_btnMgr . hide ( m_nandemuBtnBack , instant ) ;
m_btnMgr . hide ( m_nandfilePBar , instant ) ;
m_btnMgr . hide ( m_nandemuPBar , instant ) ;
m_btnMgr . hide ( m_nandfileLblMessage , instant ) ;
m_btnMgr . hide ( m_nandemuLblMessage , 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_nandemuBtnExtract , instant ) ;
2012-06-07 02:34:47 +02:00
m_btnMgr . hide ( m_nandemuBtnPartition , instant ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . hide ( m_nandemuBtnDisable , instant ) ;
m_btnMgr . hide ( m_nandemuLblInit , instant ) ;
}
void CMenu : : _showNandEmu ( void )
{
_setBg ( m_nandemuBg , m_nandemuBg ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblTitle , _t ( " cfgne10 " , L " NAND Emulation Settings " ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . show ( m_nandemuLblTitle ) ;
m_btnMgr . show ( m_nandemuBtnBack ) ;
int i ;
2012-11-04 20:22:02 +01:00
if ( ( ( m_current_view = = COVERFLOW_CHANNEL & & ! m_cfg . getBool ( CHANNEL_DOMAIN , " disable " , true ) ) | | m_current_view = = COVERFLOW_USB ) & & ! m_locked )
2012-05-03 01:08:11 +02:00
{
m_btnMgr . show ( m_nandemuLblEmulation ) ;
m_btnMgr . show ( m_nandemuLblEmulationVal ) ;
m_btnMgr . show ( m_nandemuBtnEmulationP ) ;
m_btnMgr . show ( m_nandemuBtnEmulationM ) ;
2012-06-07 02:34:47 +02:00
}
if ( ( m_current_view = = COVERFLOW_CHANNEL | | m_current_view = = COVERFLOW_USB ) & & ! m_locked )
{
2012-05-03 01:08:11 +02:00
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 )
{
2012-11-04 20:22:02 +01:00
i = min ( max ( 0 , m_cfg . getInt ( CHANNEL_DOMAIN , " emulation " , 0 ) ) , ( int ) ARRAY_SIZE ( CMenu : : _NandEmu ) - 1 ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuLblEmulationVal , _t ( CMenu : : _NandEmu [ i ] . id , CMenu : : _NandEmu [ i ] . text ) ) ;
}
else if ( m_current_view = = COVERFLOW_USB )
{
2012-11-04 20:22:02 +01:00
i = min ( max ( 0 , m_cfg . getInt ( WII_DOMAIN , " save_emulation " , 0 ) ) , ( int ) ARRAY_SIZE ( CMenu : : _GlobalSaveEmu ) - 1 ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuLblEmulationVal , _t ( CMenu : : _GlobalSaveEmu [ i ] . id , CMenu : : _GlobalSaveEmu [ i ] . text ) ) ;
}
}
}
int CMenu : : _NandEmuCfg ( void )
{
lwp_t thread = 0 ;
SetupInput ( ) ;
_showNandEmu ( ) ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
m_thrdStop = false ;
m_thrdMessageAdded = false ;
m_nandext = false ;
2012-05-06 14:59:09 +02:00
2012-09-09 20:35:15 +02:00
while ( ! m_exit )
2012-05-03 01:08:11 +02:00
{
2012-09-09 20:35:15 +02:00
_mainLoopCommon ( ) ;
2012-05-03 01:08:11 +02:00
if ( ( BTN_HOME_PRESSED | | BTN_B_PRESSED ) & & ! m_thrdWorking )
break ;
else if ( BTN_UP_PRESSED )
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 ) ) )
{
s8 direction = m_btnMgr . selected ( m_nandemuBtnEmulationP ) ? 1 : - 1 ;
if ( m_current_view = = COVERFLOW_CHANNEL )
2012-11-04 20:22:02 +01:00
m_cfg . setInt ( CHANNEL_DOMAIN , " emulation " , ( int ) loopNum ( ( u32 ) m_cfg . getInt ( CHANNEL_DOMAIN , " emulation " , 0 ) + direction , ARRAY_SIZE ( CMenu : : _NandEmu ) ) ) ;
2012-05-03 01:08:11 +02:00
else if ( m_current_view = = COVERFLOW_USB )
2012-11-04 20:22:02 +01:00
m_cfg . setInt ( WII_DOMAIN , " save_emulation " , ( int ) loopNum ( ( u32 ) m_cfg . getInt ( WII_DOMAIN , " save_emulation " , 0 ) + direction , ARRAY_SIZE ( CMenu : : _GlobalSaveEmu ) ) ) ;
2012-05-03 01:08:11 +02:00
_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 ) ;
m_btnMgr . hide ( m_nandemuLblNandDump ) ;
m_btnMgr . hide ( m_nandemuBtnNandDump ) ;
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 " " ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , _t ( " cfgne11 " , L " Overall Progress: " ) ) ;
2012-05-03 01:08:11 +02:00
if ( m_fulldump )
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblTitle , _t ( " cfgne12 " , L " NAND Extractor " ) ) ;
2012-05-03 01:08:11 +02:00
else
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblTitle , _t ( " cfgne13 " , L " Game Save Extractor " ) ) ;
2012-05-03 01:08:11 +02:00
m_thrdStop = false ;
m_thrdProgress = 0.f ;
m_thrdWorking = true ;
LWP_CreateThread ( & thread , ( void * ( * ) ( void * ) ) CMenu : : _NandDumper , ( void * ) this , 0 , 32768 , 40 ) ;
}
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnBack ) ) )
{
m_cfg . save ( ) ;
break ;
}
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( m_thrdMessageAdded )
{
LockMutex lock ( m_mutex ) ;
m_thrdMessageAdded = false ;
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 ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandfileLblMessage , wfmt ( _fmt ( " fileprogress " , L " %d / %dKB " ) , m_fileprog / 0x400 , m_filesize / 0x400 ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuLblMessage , wfmt ( _fmt ( " dumpprogress " , L " %i%% " ) , ( int ) ( m_thrdProgress * 100.f ) ) ) ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( ! m_thrdWorking )
{
if ( m_sgdump )
m_btnMgr . setText ( m_nandfinLblDialog , wfmt ( _fmt ( " cfgne14 " , L " Extracted: %d saves / %d files / %d folders " ) , m_nandexentry , m_filesdone , m_foldersdone ) ) ;
else
m_btnMgr . setText ( m_nandfinLblDialog , wfmt ( _fmt ( " cfgne15 " , L " Extracted: %d files / %d folders " ) , m_filesdone , m_foldersdone ) ) ;
if ( m_dumpsize / 0x400 > 0x270f )
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne16 " , L " Total size: %uMB (%d blocks) " ) , ( m_dumpsize / 0x100000 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
else
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne17 " , L " Total size: %uKB (%d blocks) " ) , ( m_dumpsize / 0x400 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . show ( m_nandemuBtnBack ) ;
m_btnMgr . show ( m_nandfinLblDialog ) ;
}
}
}
_hideNandEmu ( ) ;
return 0 ;
}
2012-05-11 01:38:34 +02:00
int CMenu : : _FlashSave ( string gameId )
{
2012-11-04 20:22:02 +01:00
int emuPartition = m_cfg . getInt ( WII_DOMAIN , " savepartition " , m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , 0 ) ) ;
2012-05-11 01:38:34 +02:00
char basepath [ MAX_FAT_PATH ] ;
2012-11-04 20:22:02 +01:00
snprintf ( basepath , sizeof ( basepath ) , " %s:%s " , DeviceName [ emuPartition ] , m_cfg . getString ( WII_DOMAIN , " savepath " , m_cfg . getString ( CHANNEL_DOMAIN , " path " , " " ) ) . c_str ( ) ) ;
2012-05-11 01:38:34 +02:00
if ( ! _checkSave ( gameId , false ) )
return 0 ;
lwp_t thread = 0 ;
SetupInput ( ) ;
m_thrdStop = false ;
m_thrdMessageAdded = false ;
m_nandext = false ;
m_saveExtGameId = gameId ;
2012-09-09 20:35:15 +02:00
while ( ! m_exit )
2012-05-11 01:38:34 +02:00
{
2012-09-09 20:35:15 +02:00
_mainLoopCommon ( ) ;
2012-05-11 01:38:34 +02:00
if ( m_forceext )
{
m_forceext = false ;
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 ( " cfgne28 " , L " Game Save Flasher " ) ) ;
m_thrdStop = false ;
m_thrdProgress = 0.f ;
m_thrdWorking = true ;
LWP_CreateThread ( & thread , ( void * ( * ) ( void * ) ) CMenu : : _NandFlasher , ( void * ) this , 0 , 32768 , 40 ) ;
}
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnBack ) ) )
{
m_cfg . save ( ) ;
_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 ( " cfgne29 " , L " Flashed: %d saves / %d files / %d folders " ) , m_nandexentry , m_filesdone , m_foldersdone ) ) ;
if ( m_dumpsize / 0x400 > 0x270f )
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne16 " , L " Total size: %uMB (%d blocks) " ) , ( m_dumpsize / 0x100000 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
else
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne17 " , L " Total size: %uKB (%d blocks) " ) , ( m_dumpsize / 0x400 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
m_btnMgr . show ( m_nandemuBtnBack ) ;
m_btnMgr . show ( m_nandfinLblDialog ) ;
}
}
}
_hideNandEmu ( ) ;
return 0 ;
}
2012-05-03 01:08:11 +02:00
int CMenu : : _AutoExtractSave ( string gameId )
{
2012-06-07 02:34:47 +02:00
string emuPath ;
if ( m_current_view = = COVERFLOW_CHANNEL )
2012-11-04 20:22:02 +01:00
m_partRequest = m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , - 1 ) ;
2012-06-07 02:34:47 +02:00
else if ( m_current_view = = COVERFLOW_USB )
2012-11-04 20:22:02 +01:00
m_partRequest = m_cfg . getInt ( WII_DOMAIN , " savepartition " , - 1 ) ;
2012-06-07 02:34:47 +02:00
int emuPartition = _FindEmuPart ( & emuPath , m_partRequest , false ) ;
2012-05-17 02:43:42 +02:00
if ( emuPartition < 0 )
2012-06-07 02:34:47 +02:00
emuPartition = _FindEmuPart ( & emuPath , m_partRequest , true ) ;
2012-05-08 02:59:53 +02:00
2012-05-11 01:38:34 +02:00
if ( ! _checkSave ( gameId , true ) )
return 1 ;
if ( ! m_forceext & & _checkSave ( gameId , false ) )
2012-05-08 02:59:53 +02:00
return 1 ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
lwp_t thread = 0 ;
SetupInput ( ) ;
m_thrdStop = false ;
m_thrdMessageAdded = false ;
m_nandext = false ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( ! m_forceext )
{
m_btnMgr . setText ( m_nandemuBtnExtract , _t ( " cfgne24 " , L " Extract save " ) ) ;
m_btnMgr . setText ( m_nandemuBtnDisable , _t ( " cfgne25 " , L " Create new save " ) ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblInit , _t ( " cfgne26 " , L " A save file for this game was created on real NAND. Extract existing save file from real NAND or create new file for NAND Emulation? " ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . show ( m_nandemuBtnExtract ) ;
m_btnMgr . show ( m_nandemuBtnDisable ) ;
m_btnMgr . show ( m_nandemuLblInit ) ;
}
m_saveExtGameId = gameId ;
2012-05-06 14:59:09 +02:00
2012-09-09 20:35:15 +02:00
while ( ! m_exit )
2012-05-03 01:08:11 +02:00
{
2012-09-09 20:35:15 +02:00
_mainLoopCommon ( ) ;
2012-05-03 01:08:11 +02:00
if ( ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnExtract ) ) ) | | m_forceext )
{
m_forceext = false ;
m_fulldump = false ;
m_btnMgr . hide ( m_nandemuBtnExtract ) ;
m_btnMgr . hide ( m_nandemuBtnDisable ) ;
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 " " ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , _t ( " cfgne11 " , L " Overall Progress: " ) ) ;
m_btnMgr . setText ( m_nandemuLblTitle , _t ( " cfgne13 " , L " Game Save Extractor " ) ) ;
2012-05-03 01:08:11 +02:00
m_thrdStop = false ;
m_thrdProgress = 0.f ;
m_thrdWorking = true ;
LWP_CreateThread ( & thread , ( void * ( * ) ( void * ) ) CMenu : : _NandDumper , ( void * ) this , 0 , 32768 , 40 ) ;
}
2012-05-11 01:38:34 +02:00
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnDisable ) ) )
2012-05-03 01:08:11 +02:00
{
2012-06-07 02:34:47 +02:00
char basepath [ MAX_FAT_PATH ] ;
snprintf ( basepath , sizeof ( basepath ) , " %s:%s " , DeviceName [ emuPartition ] , emuPath . c_str ( ) ) ;
2012-10-15 21:16:14 +02:00
NandHandle . CreatePath ( " %s/import " , basepath ) ;
NandHandle . CreatePath ( " %s/meta " , basepath ) ;
NandHandle . CreatePath ( " %s/shared1 " , basepath ) ;
NandHandle . CreatePath ( " %s/shared2 " , basepath ) ;
NandHandle . CreatePath ( " %s/sys " , basepath ) ;
NandHandle . CreatePath ( " %s/title " , basepath ) ;
NandHandle . CreatePath ( " %s/ticket " , basepath ) ;
NandHandle . CreatePath ( " %s/tmp " , basepath ) ;
2012-05-03 01:08:11 +02:00
_hideNandEmu ( ) ;
return 0 ;
}
2012-05-11 01:38:34 +02:00
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnBack ) ) )
{
m_cfg . save ( ) ;
_hideNandEmu ( ) ;
return 1 ;
}
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( m_thrdMessageAdded )
{
LockMutex lock ( m_mutex ) ;
m_thrdMessageAdded = false ;
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 ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandfileLblMessage , wfmt ( _fmt ( " fileprogress " , L " %d / %dKB " ) , m_fileprog / 0x400 , m_filesize / 0x400 ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuLblMessage , wfmt ( _fmt ( " dumpprogress " , L " %i%% " ) , ( int ) ( m_thrdProgress * 100.f ) ) ) ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( ! m_thrdWorking )
{
m_btnMgr . setText ( m_nandfinLblDialog , wfmt ( _fmt ( " cfgne14 " , L " Extracted: %d saves / %d files / %d folders " ) , m_nandexentry , m_filesdone , m_foldersdone ) ) ;
if ( m_dumpsize / 0x400 > 0x270f )
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne16 " , L " Total size: %uMB (%d blocks) " ) , ( m_dumpsize / 0x100000 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
else
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne17 " , L " Total size: %uKB (%d blocks) " ) , ( m_dumpsize / 0x400 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
2012-05-11 01:38:34 +02:00
m_btnMgr . show ( m_nandemuBtnBack ) ;
m_btnMgr . show ( m_nandfinLblDialog ) ;
2012-05-03 01:08:11 +02:00
}
}
}
_hideNandEmu ( ) ;
return 0 ;
}
int CMenu : : _AutoCreateNand ( void )
{
lwp_t thread = 0 ;
SetupInput ( ) ;
2012-06-07 02:34:47 +02:00
string emuPath ;
2012-05-03 01:08:11 +02:00
m_thrdStop = false ;
m_thrdMessageAdded = false ;
2012-06-07 02:34:47 +02:00
m_nandext = false ;
m_tempView = false ;
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuBtnExtract , _t ( " cfgne5 " , L " Extract NAND " ) ) ;
m_btnMgr . setText ( m_nandemuBtnDisable , _t ( " cfgne22 " , L " Disable NAND Emulation " ) ) ;
2012-06-07 02:34:47 +02:00
m_btnMgr . setText ( m_nandemuBtnPartition , _t ( " cfgne31 " , L " Select Partition " ) ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblInit , _t ( " cfgne23 " , L " Welcome to WiiFlow. I have not found a valid NAND for NAND Emulation. Click Extract to extract your NAND, or click disable to disable NAND Emulation. " ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . show ( m_nandemuBtnExtract ) ;
2012-06-07 02:34:47 +02:00
m_btnMgr . show ( m_nandemuBtnDisable ) ;
m_btnMgr . show ( m_nandemuBtnPartition ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . show ( m_nandemuLblInit ) ;
2012-05-06 14:59:09 +02:00
2012-09-09 20:35:15 +02:00
while ( ! m_exit )
2012-05-03 01:08:11 +02:00
{
2012-09-09 20:35:15 +02:00
_mainLoopCommon ( ) ;
2012-05-03 01:08:11 +02:00
if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnExtract ) ) )
{
m_fulldump = true ;
m_btnMgr . hide ( m_nandemuBtnExtract ) ;
2012-06-07 02:34:47 +02:00
m_btnMgr . hide ( m_nandemuBtnDisable ) ;
m_btnMgr . hide ( m_nandemuBtnPartition ) ;
2012-05-03 01:08:11 +02:00
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 " " ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , _t ( " cfgne11 " , L " Overall Progress: " ) ) ;
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblTitle , _t ( " cfgne12 " , L " NAND Extractor " ) ) ;
2012-05-03 01:08:11 +02:00
m_thrdStop = false ;
m_thrdProgress = 0.f ;
m_thrdWorking = true ;
LWP_CreateThread ( & thread , ( void * ( * ) ( void * ) ) CMenu : : _NandDumper , ( void * ) this , 0 , 32768 , 40 ) ;
}
2012-05-11 01:38:34 +02:00
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnDisable ) ) )
2012-05-03 01:08:11 +02:00
{
_hideNandEmu ( ) ;
return 0 ;
}
2012-06-07 02:34:47 +02:00
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnPartition ) ) )
{
if ( m_current_view = = COVERFLOW_USB )
{
m_tempView = true ;
m_current_view = COVERFLOW_CHANNEL ;
}
_hideNandEmu ( ) ;
_config ( 1 ) ;
if ( m_tempView )
{
m_current_view = COVERFLOW_USB ;
m_tempView = false ;
return 0 ;
}
return 1 ;
}
2012-05-11 01:38:34 +02:00
else if ( BTN_A_PRESSED & & ( m_btnMgr . selected ( m_nandemuBtnBack ) ) )
{
m_cfg . save ( ) ;
_hideNandEmu ( ) ;
return 1 ;
}
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( m_thrdMessageAdded )
{
LockMutex lock ( m_mutex ) ;
m_thrdMessageAdded = false ;
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 ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandfileLblMessage , wfmt ( _fmt ( " fileprogress " , L " %d / %dKB " ) , m_fileprog / 0x400 , m_filesize / 0x400 ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuLblMessage , wfmt ( _fmt ( " dumpprogress " , L " %i%% " ) , ( int ) ( m_thrdProgress * 100.f ) ) ) ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
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 )
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne16 " , L " Total size: %uMB (%d blocks) " ) , ( m_dumpsize / 0x100000 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
else
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblDialog , wfmt ( _fmt ( " cfgne17 " , L " Total size: %uKB (%d blocks) " ) , ( m_dumpsize / 0x400 ) , ( m_dumpsize / 0x8000 ) > > 2 ) ) ;
2012-05-03 01:08:11 +02:00
2012-05-11 01:38:34 +02:00
m_btnMgr . show ( m_nandemuBtnBack ) ;
m_btnMgr . show ( m_nandfinLblDialog ) ;
2012-05-03 01:08:11 +02:00
}
}
}
_hideNandEmu ( ) ;
return 0 ;
}
2012-05-11 01:38:34 +02:00
int CMenu : : _NandFlasher ( void * obj )
{
CMenu & m = * ( CMenu * ) obj ;
string emuPath ;
2012-06-07 02:34:47 +02:00
2012-05-11 01:38:34 +02:00
char source [ MAX_FAT_PATH ] ;
char dest [ ISFS_MAXPATH ] ;
if ( m . m_current_view = = COVERFLOW_CHANNEL )
2012-11-04 20:22:02 +01:00
m . m_partRequest = m . m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , - 1 ) ;
2012-05-11 01:38:34 +02:00
else if ( m . m_current_view = = COVERFLOW_USB )
2012-11-04 20:22:02 +01:00
m . m_partRequest = m . m_cfg . getInt ( WII_DOMAIN , " savepartition " , - 1 ) ;
2012-05-11 01:38:34 +02:00
2012-11-18 14:40:26 +01:00
const char * SaveGameID = m . m_saveExtGameId . c_str ( ) ;
2012-06-07 02:34:47 +02:00
int emuPartition = m . _FindEmuPart ( & emuPath , m . m_partRequest , false ) ;
2012-11-18 14:40:26 +01:00
int flashID = SaveGameID [ 0 ] < < 24 | SaveGameID [ 1 ] < < 16 | SaveGameID [ 2 ] < < 8 | SaveGameID [ 3 ] ;
2012-05-11 01:38:34 +02:00
2012-11-18 14:40:26 +01:00
if ( _saveExists ( fmt ( " %s:%s/title/00010000/%08x " , DeviceName [ emuPartition ] , emuPath . c_str ( ) , flashID ) ) )
2012-05-11 01:38:34 +02:00
{
snprintf ( source , sizeof ( source ) , " %s:%s/title/00010000/%08x " , DeviceName [ emuPartition ] , emuPath . c_str ( ) , flashID ) ;
snprintf ( dest , sizeof ( dest ) , " /title/00010000/%08x " , flashID ) ;
}
2012-11-18 14:40:26 +01:00
else if ( _saveExists ( fmt ( " %s:%s/title/00010004/%08x " , DeviceName [ emuPartition ] , emuPath . c_str ( ) , flashID ) ) )
2012-05-11 01:38:34 +02:00
{
snprintf ( source , sizeof ( source ) , " %s:%s/title/00010004/%08x " , DeviceName [ emuPartition ] , emuPath . c_str ( ) , flashID ) ;
snprintf ( dest , sizeof ( dest ) , " /title/00010004/%08x " , flashID ) ;
}
2012-10-15 21:16:14 +02:00
NandHandle . ResetCounters ( ) ;
2012-05-11 01:38:34 +02:00
m . m_nandexentry = 1 ;
2012-10-15 21:16:14 +02:00
m . m_dumpsize = NandHandle . CalcFlashSize ( source , CMenu : : _ShowProgress , obj ) ;
2012-06-08 15:05:21 +02:00
m_nandext = true ;
2012-10-15 21:16:14 +02:00
NandHandle . FlashToNAND ( source , dest , CMenu : : _ShowProgress , obj ) ;
2012-05-11 01:38:34 +02:00
m . m_thrdWorking = false ;
LWP_MutexLock ( m . m_mutex ) ;
2012-06-08 15:05:21 +02:00
m . m_btnMgr . hide ( m_nandfilePBar ) ;
m . m_btnMgr . hide ( m_nandfileLblMessage ) ;
2012-05-11 01:38:34 +02:00
m . _setDumpMsg ( m . _t ( " cfgne30 " , L " Flashing save files finished! " ) , 1.f , 1.f ) ;
LWP_MutexUnlock ( m . m_mutex ) ;
return 0 ;
}
2012-05-03 01:08:11 +02:00
int CMenu : : _NandDumper ( void * obj )
{
CMenu & m = * ( CMenu * ) obj ;
string emuPath ;
int emuPartition = - 1 ;
2012-06-08 15:05:21 +02:00
m_nandext = false ;
m_sgdump = false ;
2012-05-03 01:08:11 +02:00
m . m_dumpsize = 0 ;
m . m_filesdone = 0 ;
m . m_foldersdone = 0 ;
2012-05-06 14:59:09 +02:00
2012-10-15 21:16:14 +02:00
NandHandle . ResetCounters ( ) ;
2012-06-08 15:05:21 +02:00
2012-05-03 01:08:11 +02:00
if ( m . m_current_view = = COVERFLOW_CHANNEL )
2012-11-04 20:22:02 +01:00
m . m_partRequest = m . m_cfg . getInt ( CHANNEL_DOMAIN , " partition " , - 1 ) ;
2012-05-03 01:08:11 +02:00
else if ( m . m_current_view = = COVERFLOW_USB )
2012-11-04 20:22:02 +01:00
m . m_partRequest = m . m_cfg . getInt ( WII_DOMAIN , " savepartition " , - 1 ) ;
2012-06-08 15:05:21 +02:00
2012-06-07 02:34:47 +02:00
emuPartition = m . _FindEmuPart ( & emuPath , m . m_partRequest , true ) ;
2012-05-06 14:59:09 +02:00
2012-06-07 02:34:47 +02:00
if ( emuPartition < 0 )
2012-05-03 01:08:11 +02:00
{
2012-05-06 15:55:56 +02:00
m . error ( m . _t ( " cfgne8 " , L " No valid FAT partition found for NAND Emulation! " ) ) ;
2012-05-03 01:08:11 +02:00
return 0 ;
}
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
char basepath [ 64 ] ;
2012-05-04 14:30:43 +02:00
snprintf ( basepath , sizeof ( basepath ) , " %s:%s " , DeviceName [ emuPartition ] , emuPath . c_str ( ) ) ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
LWP_MutexLock ( m . m_mutex ) ;
2012-05-06 15:55:56 +02:00
m . _setDumpMsg ( m . _t ( " cfgne27 " , L " Calculating space needed for extraction... " ) , 0.f , 0.f ) ;
2012-05-03 01:08:11 +02:00
LWP_MutexUnlock ( m . m_mutex ) ;
2012-05-06 14:59:09 +02:00
2012-06-08 15:05:21 +02:00
if ( m_fulldump )
2012-05-03 01:08:11 +02:00
{
2012-10-15 21:16:14 +02:00
m . m_dumpsize = NandHandle . CalcDumpSpace ( " / " , CMenu : : _ShowProgress , obj ) ;
2012-06-08 15:05:21 +02:00
m_nandext = true ;
2012-10-15 21:16:14 +02:00
NandHandle . DoNandDump ( " / " , basepath , CMenu : : _ShowProgress , obj ) ;
2012-05-03 01:08:11 +02:00
}
else
{
2012-06-08 15:05:21 +02:00
bool missingOnly = ! m_saveall ;
2012-05-06 14:03:43 +02:00
vector < string > saveList ;
2012-06-08 15:05:21 +02:00
m_sgdump = true ;
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
if ( m . m_saveExtGameId . empty ( ) )
{
m . m_nandexentry = 0 ;
2012-10-04 13:37:53 +02:00
saveList . reserve ( m_gameList . size ( ) ) ;
for ( u32 i = 0 ; i < m_gameList . size ( ) & & ! m . m_thrdStop ; + + i )
2012-05-03 01:08:11 +02:00
{
LWP_MutexLock ( m . m_mutex ) ;
m . _setDumpMsg ( m . _t ( " cfgne18 " , L " Listing game saves to extract... " ) , 0.f , 0.f ) ;
LWP_MutexUnlock ( m . m_mutex ) ;
2012-05-06 14:59:09 +02:00
2012-10-04 13:37:53 +02:00
string id ( ( const char * ) m_gameList [ i ] . id , 4 ) ;
2012-05-06 14:59:09 +02:00
2012-05-11 01:38:34 +02:00
if ( ! missingOnly | | ! m . _checkSave ( id , false ) )
2012-05-03 01:08:11 +02:00
{
2012-05-11 01:38:34 +02:00
if ( m . _checkSave ( id , true ) )
2012-05-03 01:08:11 +02:00
{
m . m_nandexentry + + ;
saveList . push_back ( id ) ;
}
2012-05-06 14:59:09 +02:00
}
2012-05-03 01:08:11 +02:00
}
}
else
2012-05-11 01:38:34 +02:00
{
m . m_nandexentry = 1 ;
2012-05-03 01:08:11 +02:00
saveList . push_back ( m . m_saveExtGameId ) ;
2012-05-11 01:38:34 +02:00
}
2012-05-03 01:08:11 +02:00
for ( u32 i = 0 ; i < saveList . size ( ) & & ! m . m_thrdStop ; + + i )
{
char source [ ISFS_MAXPATH ] ;
int savePath = saveList [ i ] . c_str ( ) [ 0 ] < < 24 | saveList [ i ] . c_str ( ) [ 1 ] < < 16 | saveList [ i ] . c_str ( ) [ 2 ] < < 8 | saveList [ i ] . c_str ( ) [ 3 ] ;
2012-05-11 01:38:34 +02:00
snprintf ( source , sizeof ( source ) , " /title/00010000/%08x " , savePath ) ;
if ( ! m . _checkSave ( saveList [ i ] , true ) )
snprintf ( source , sizeof ( source ) , " /title/00010004/%08x " , savePath ) ;
2012-06-08 15:05:21 +02:00
2012-10-15 21:16:14 +02:00
m . m_dumpsize = NandHandle . CalcDumpSpace ( source , CMenu : : _ShowProgress , obj ) ;
2012-05-03 01:08:11 +02:00
}
for ( u32 i = 0 ; i < saveList . size ( ) & & ! m . m_thrdStop ; + + i )
{
char source [ ISFS_MAXPATH ] ;
int savePath = saveList [ i ] . c_str ( ) [ 0 ] < < 24 | saveList [ i ] . c_str ( ) [ 1 ] < < 16 | saveList [ i ] . c_str ( ) [ 2 ] < < 8 | saveList [ i ] . c_str ( ) [ 3 ] ;
2012-05-08 02:59:53 +02:00
snprintf ( source , sizeof ( source ) , " /title/00010000/%08x " , savePath ) ;
2012-05-11 01:38:34 +02:00
if ( ! m . _checkSave ( saveList [ i ] , true ) )
2012-05-08 02:59:53 +02:00
snprintf ( source , sizeof ( source ) , " /title/00010004/%08x " , savePath ) ;
2012-06-08 15:05:21 +02:00
m_nandext = true ;
2012-10-15 21:16:14 +02:00
NandHandle . DoNandDump ( source , basepath , CMenu : : _ShowProgress , obj ) ;
2012-05-03 01:08:11 +02:00
}
}
2012-05-06 14:59:09 +02:00
2012-05-03 01:08:11 +02:00
m . m_thrdWorking = false ;
LWP_MutexLock ( m . m_mutex ) ;
2012-06-08 15:05:21 +02:00
m . m_btnMgr . hide ( m_nandfilePBar ) ;
m . m_btnMgr . hide ( m_nandfileLblMessage ) ;
2012-05-03 01:08:11 +02:00
m . _setDumpMsg ( m . _t ( " cfgne19 " , L " Extraction finished! " ) , 1.f , 1.f ) ;
LWP_MutexUnlock ( m . m_mutex ) ;
return 0 ;
}
2012-11-03 20:16:03 +01:00
void CMenu : : _initNandEmuMenu ( )
2012-05-03 01:08:11 +02:00
{
2012-11-03 20:16:03 +01:00
_addUserLabels ( m_nandemuLblUser , ARRAY_SIZE ( m_nandemuLblUser ) , " NANDEMU " ) ;
m_nandemuBg = _texture ( " NANDEMU/BG " , " texture " , theme . bg , false ) ;
m_nandemuLblTitle = _addTitle ( " NANDEMU/TITLE " , theme . titleFont , L " " , 20 , 30 , 600 , 60 , theme . titleFontColor , FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE ) ;
m_nandfileLblMessage = _addLabel ( " NANDEMU/FMESSAGE " , theme . lblFont , L " " , 40 , 230 , 560 , 100 , theme . lblFontColor , FTGX_JUSTIFY_CENTER | FTGX_ALIGN_TOP ) ;
m_nandemuLblMessage = _addLabel ( " NANDEMU/MESSAGE " , theme . lblFont , L " " , 40 , 350 , 560 , 100 , theme . lblFontColor , FTGX_JUSTIFY_CENTER | FTGX_ALIGN_TOP ) ;
m_nandfileLblDialog = _addLabel ( " NANDEMU/FDIALOG " , theme . lblFont , L " " , 40 , 60 , 560 , 200 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandfinLblDialog = _addLabel ( " NANDEMU/FINDIALOG " , theme . lblFont , L " " , 40 , 120 , 560 , 200 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandemuLblDialog = _addLabel ( " NANDEMU/DIALOG " , theme . lblFont , L " " , 40 , 180 , 560 , 200 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandfilePBar = _addProgressBar ( " NANDEMU/FILEPROGRESS_BAR " , 40 , 200 , 560 , 20 ) ;
m_nandemuPBar = _addProgressBar ( " NANDEMU/PROGRESS_BAR " , 40 , 320 , 560 , 20 ) ;
m_nandemuLblEmulation = _addLabel ( " NANDEMU/EMU_SAVE " , theme . lblFont , L " " , 40 , 130 , 340 , 56 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandemuLblEmulationVal = _addLabel ( " NANDEMU/EMU_SAVE_BTN_GLOBAL " , theme . btnFont , L " " , 400 , 130 , 144 , 56 , theme . btnFontColor , FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE , theme . btnTexC ) ;
m_nandemuBtnEmulationM = _addPicButton ( " NANDEMU/EMU_SAVE_MINUS " , theme . btnTexMinus , theme . btnTexMinusS , 344 , 130 , 56 , 56 ) ;
m_nandemuBtnEmulationP = _addPicButton ( " NANDEMU/EMU_SAVE_PLUS " , theme . btnTexPlus , theme . btnTexPlusS , 544 , 130 , 56 , 56 ) ;
m_nandemuLblSaveDump = _addLabel ( " NANDEMU/SAVE_DUMP " , theme . lblFont , L " " , 40 , 190 , 340 , 56 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandemuBtnAll = _addButton ( " NANDEMU/ALL_BTN " , theme . btnFont , L " " , 350 , 190 , 250 , 56 , theme . btnFontColor ) ;
m_nandemuBtnMissing = _addButton ( " NANDEMU/MISSING_BTN " , theme . btnFont , L " " , 350 , 250 , 250 , 56 , theme . btnFontColor ) ;
m_nandemuLblNandDump = _addLabel ( " NANDEMU/NAND_DUMP " , theme . lblFont , L " " , 40 , 310 , 340 , 56 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
m_nandemuBtnNandDump = _addButton ( " NANDEMU/NAND_DUMP_BTN " , theme . btnFont , L " " , 350 , 310 , 250 , 56 , theme . btnFontColor ) ;
m_nandemuBtnBack = _addButton ( " NANDEMU/BACK_BTN " , theme . btnFont , L " " , 420 , 400 , 200 , 56 , theme . btnFontColor ) ;
m_nandemuBtnExtract = _addButton ( " NANDEMU/EXTRACT " , theme . titleFont , L " " , 72 , 180 , 496 , 56 , theme . titleFontColor ) ;
m_nandemuBtnDisable = _addButton ( " NANDEMU/DISABLE " , theme . titleFont , L " " , 72 , 270 , 496 , 56 , theme . titleFontColor ) ;
m_nandemuBtnPartition = _addButton ( " NANDEMU/PARTITION " , theme . titleFont , L " " , 72 , 360 , 496 , 56 , theme . titleFontColor ) ;
m_nandemuLblInit = _addLabel ( " NANDEMU/INIT " , theme . lblFont , L " " , 40 , 40 , 560 , 140 , theme . lblFontColor , FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE ) ;
2012-05-06 14:59:09 +02:00
2012-07-29 00:38:46 +02:00
_setHideAnim ( m_nandemuLblTitle , " NANDEMU/TITLE " , 0 , - 100 , 0.f , 0.f ) ;
2012-05-03 01:08:11 +02:00
_setHideAnim ( m_nandfileLblMessage , " NANDEMU/FMESSAGE " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblMessage , " NANDEMU/MESSAGE " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandfileLblDialog , " NANDEMU/FDIALOG " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandfinLblDialog , " NANDEMU/FINDIALOG " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblDialog , " NANDEMU/DIALOG " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandfilePBar , " NANDEMU/FILEPROGRESS_BAR " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuPBar , " NANDEMU/PROGRESS_BAR " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblEmulation , " NANDEMU/EMU_SAVE " , 100 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblEmulationVal , " NANDEMU/EMU_SAVE_BTN_GLOBAL " , 0 , 0 , 1.f , - 1.f ) ;
_setHideAnim ( m_nandemuBtnEmulationM , " NANDEMU/EMU_SAVE_MINUS " , 0 , 0 , 1.f , - 1.f ) ;
_setHideAnim ( m_nandemuBtnEmulationP , " NANDEMU/EMU_SAVE_PLUS " , 0 , 0 , 1.f , - 1.f ) ;
_setHideAnim ( m_nandemuLblSaveDump , " NANDEMU/SAVE_DUMP " , 100 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuBtnAll , " NANDEMU/ALL_BTN " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuBtnMissing , " NANDEMU/MISSING_BTN " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblNandDump , " NANDEMU/NAND_DUMP " , 100 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuBtnNandDump , " NANDEMU/NAND_DUMP_BTN " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuBtnBack , " NANDEMU/BACK_BTN " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuBtnExtract , " NANDEMU/EXTRACT " , 0 , 0 , - 2.f , 0.f ) ;
2012-06-07 02:34:47 +02:00
_setHideAnim ( m_nandemuBtnPartition , " NANDEMU/PARTITION " , 0 , 0 , - 2.f , 0.f ) ;
2012-05-03 01:08:11 +02:00
_setHideAnim ( m_nandemuBtnDisable , " NANDEMU/DISABLE " , 0 , 0 , - 2.f , 0.f ) ;
_setHideAnim ( m_nandemuLblInit , " NANDEMU/INIT " , 100 , 0 , - 2.f , 0.f ) ;
_hideNandEmu ( true ) ;
_textNandEmu ( ) ;
}
void CMenu : : _textNandEmu ( void )
{
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblEmulation , _t ( " cfgne1 " , L " NAND Emulation " ) ) ;
2012-05-06 15:55:56 +02:00
m_btnMgr . setText ( m_nandemuLblSaveDump , _t ( " cfgne2 " , L " Extract Game Saves " ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuBtnAll , _t ( " cfgne3 " , L " All " ) ) ;
m_btnMgr . setText ( m_nandemuBtnMissing , _t ( " cfgne4 " , L " Missing " ) ) ;
2012-05-06 14:59:09 +02:00
m_btnMgr . setText ( m_nandemuLblNandDump , _t ( " cfgne5 " , L " Extract NAND " ) ) ;
2012-05-03 01:08:11 +02:00
m_btnMgr . setText ( m_nandemuBtnNandDump , _t ( " cfgne6 " , L " Start " ) ) ;
m_btnMgr . setText ( m_nandemuBtnBack , _t ( " cfgne7 " , L " Back " ) ) ;
2012-06-08 15:05:21 +02:00
}