mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-30 15:14:18 +01:00
-DML view now can see games on usb too
-added possibility to copy gamecube games from usb to sd card, after copy process game will be started (copy takes 5-10 minutes) (issue 12) -added possibility to install gamecube games to usb fat partitions -fixed game name not displayed in delete game dialog -changed naming scheme of partition name in top-right corner in coverflow, now looks like DML [USB1], name depends on view
This commit is contained in:
parent
fa7da0a437
commit
f1d0386b3c
268
source/gc/fileOps.c
Normal file
268
source/gc/fileOps.c
Normal file
@ -0,0 +1,268 @@
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fsop contains coomprensive set of function for file and folder handling
|
||||
|
||||
en exposed s_fsop fsop structure can be used by callback to update operation status
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h> //for mkdir
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include "fileOps.h"
|
||||
#include "memory/mem2.hpp"
|
||||
#include "utils.h"
|
||||
|
||||
s_fsop fsop;
|
||||
|
||||
// return false if the file doesn't exist
|
||||
bool fsop_GetFileSizeBytes (char *path, size_t *filesize) // for me stats st_size report always 0 :(
|
||||
{
|
||||
FILE *f;
|
||||
size_t size = 0;
|
||||
|
||||
f = fopen(path, "rb");
|
||||
if (!f)
|
||||
{
|
||||
if (filesize) *filesize = size;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get file size
|
||||
fseek( f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
if (filesize) *filesize = size;
|
||||
SAFE_CLOSE(f);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Recursive fsop_GetFolderBytes
|
||||
*/
|
||||
u64 fsop_GetFolderBytes (char *source)
|
||||
{
|
||||
DIR *pdir;
|
||||
struct dirent *pent;
|
||||
char newSource[300];
|
||||
u64 bytes = 0;
|
||||
|
||||
pdir=opendir(source);
|
||||
|
||||
while ((pent=readdir(pdir)) != NULL)
|
||||
{
|
||||
// Skip it
|
||||
if (strcmp (pent->d_name, ".") == 0 || strcmp (pent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
sprintf (newSource, "%s/%s", source, pent->d_name);
|
||||
|
||||
// If it is a folder... recurse...
|
||||
if (fsop_DirExist (newSource))
|
||||
{
|
||||
bytes += fsop_GetFolderBytes (newSource);
|
||||
}
|
||||
else // It is a file !
|
||||
{
|
||||
size_t s;
|
||||
fsop_GetFileSizeBytes (newSource, &s);
|
||||
bytes += s;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(pdir);
|
||||
|
||||
//Debug ("fsop_GetFolderBytes (%s) = %llu", source, bytes);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
u32 fsop_GetFolderKb (char *source)
|
||||
{
|
||||
u32 ret = (u32) round ((double)fsop_GetFolderBytes (source) / 1000.0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 fsop_GetFreeSpaceKb (char *path) // Return free kb on the device passed
|
||||
{
|
||||
struct statvfs s;
|
||||
|
||||
statvfs (path, &s);
|
||||
|
||||
u32 ret = (u32)round( ((double)s.f_bfree / 1000.0) * s.f_bsize);
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
|
||||
bool fsop_DirExist (char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
dir=opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fsop_CopyFile (char *source, char *target, progress_callback_t spinner, void *spinner_data)
|
||||
{
|
||||
int err = 0;
|
||||
fsop.breakop = 0;
|
||||
|
||||
u8 *buff = NULL;
|
||||
u32 size;
|
||||
u32 bytes, rb,wb;
|
||||
u32 block = 71680; //70KB
|
||||
FILE *fs = NULL, *ft = NULL;
|
||||
|
||||
fs = fopen(source, "rb");
|
||||
if (!fs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ft = fopen(target, "wt");
|
||||
if (!ft)
|
||||
{
|
||||
SAFE_CLOSE(fs);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get file size
|
||||
fseek (fs, 0, SEEK_END);
|
||||
size = ftell(fs);
|
||||
|
||||
fsop.size = size;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
SAFE_CLOSE(fs);
|
||||
SAFE_CLOSE(ft);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return to beginning....
|
||||
fseek(fs, 0, SEEK_SET);
|
||||
|
||||
buff = MEM2_alloc(block);
|
||||
if (buff == NULL)
|
||||
{
|
||||
SAFE_CLOSE(fs);
|
||||
return false;
|
||||
}
|
||||
|
||||
bytes = 0;
|
||||
bool spinnerFlag = false;
|
||||
if (strstr (source, "game.iso")) {
|
||||
spinner(bytes, size, spinner_data);
|
||||
spinnerFlag = true;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
rb = fread(buff, 1, block, fs);
|
||||
wb = fwrite(buff, 1, rb, ft);
|
||||
|
||||
if (wb != wb) err = 1;
|
||||
if (rb == 0) err = 1;
|
||||
bytes += rb;
|
||||
|
||||
if (spinnerFlag) spinner(bytes, size, spinner_data);
|
||||
|
||||
fsop.multy.bytes += rb;
|
||||
fsop.bytes = bytes;
|
||||
|
||||
if (fsop.breakop) break;
|
||||
}
|
||||
while (bytes < size && err == 0);
|
||||
|
||||
SAFE_CLOSE(fs);
|
||||
SAFE_CLOSE(ft);
|
||||
MEM2_free(buff);
|
||||
|
||||
if (err) unlink (target);
|
||||
|
||||
if (fsop.breakop || err) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Semplified folder make
|
||||
*/
|
||||
int fsop_MakeFolder (char *path)
|
||||
{
|
||||
if (mkdir(path, S_IREAD | S_IWRITE) == 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Recursive copyfolder
|
||||
*/
|
||||
static bool doCopyFolder (char *source, char *target, progress_callback_t spinner, void *spinner_data)
|
||||
{
|
||||
DIR *pdir;
|
||||
struct dirent *pent;
|
||||
char newSource[300], newTarget[300];
|
||||
bool ret = true;
|
||||
|
||||
// If target folder doesn't exist, create it !
|
||||
if (!fsop_DirExist (target))
|
||||
{
|
||||
fsop_MakeFolder (target);
|
||||
}
|
||||
|
||||
pdir=opendir(source);
|
||||
|
||||
while ((pent=readdir(pdir)) != NULL && ret == true)
|
||||
{
|
||||
// Skip it
|
||||
if (strcmp (pent->d_name, ".") == 0 || strcmp (pent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
sprintf (newSource, "%s/%s", source, pent->d_name);
|
||||
sprintf (newTarget, "%s/%s", target, pent->d_name);
|
||||
|
||||
// If it is a folder... recurse...
|
||||
if (fsop_DirExist (newSource))
|
||||
{
|
||||
ret = doCopyFolder (newSource, newTarget, spinner, spinner_data);
|
||||
}
|
||||
else // It is a file !
|
||||
{
|
||||
strcpy (fsop.op, pent->d_name);
|
||||
ret = fsop_CopyFile (newSource, newTarget, spinner, spinner_data);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(pdir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool fsop_CopyFolder (char *source, char *target, progress_callback_t spinner, void *spinner_data)
|
||||
{
|
||||
fsop.breakop = 0;
|
||||
fsop.multy.startms = ticks_to_millisecs(gettime());
|
||||
fsop.multy.bytes = 0;
|
||||
fsop.multy.size = fsop_GetFolderBytes (source);
|
||||
|
||||
return doCopyFolder (source, target, spinner, spinner_data);
|
||||
}
|
46
source/gc/fileOps.h
Normal file
46
source/gc/fileOps.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef _FILEOPS
|
||||
#define _FILEOPS
|
||||
|
||||
typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 size, bytes; // for operation that uses more than one file
|
||||
u32 startms;
|
||||
}
|
||||
s_fsopmulty;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char op[256]; // Calling process can set filename or any other info that fit
|
||||
|
||||
u32 size, bytes;
|
||||
|
||||
s_fsopmulty multy;
|
||||
|
||||
int flag1; // user defined flag
|
||||
bool breakop; // allow to stop a long operation
|
||||
}
|
||||
s_fsop;
|
||||
|
||||
extern s_fsop fsop;
|
||||
|
||||
bool fsop_GetFileSizeBytes (char *path, size_t *filesize);
|
||||
u64 fsop_GetFolderBytes (char *source);
|
||||
u32 fsop_GetFolderKb (char *source);
|
||||
u32 fsop_GetFreeSpaceKb (char *path);
|
||||
bool fsop_DirExist (char *path);
|
||||
bool fsop_CopyFile (char *source, char *target, progress_callback_t spinner, void *spinner_data);
|
||||
int fsop_MakeFolder (char *path);
|
||||
bool fsop_CopyFolder (char *source, char *target, progress_callback_t spinner, void *spinner_data);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -4,6 +4,7 @@
|
||||
#include <dirent.h>
|
||||
#include "gc.h"
|
||||
#include "gecko.h"
|
||||
#include "fileOps.h"
|
||||
|
||||
#define MAX_FAT_PATH 1024
|
||||
|
||||
@ -94,18 +95,18 @@ void set_language(u8 lang)
|
||||
while(!__SYS_SyncSram());
|
||||
}
|
||||
|
||||
void DML_RemoveGame(const char *discid)
|
||||
void DML_RemoveGame(const char *discid, const char* partition)
|
||||
{
|
||||
int num = 6;
|
||||
const char *fl[6] = {"sd:/games/%s/game.iso","sd:/games/%s/sys/boot.bin","sd:/games/%s/sys/bi2.bin",
|
||||
"sd:/games/%s/sys/apploader.img","sd:/games/%s/sys","sd:/games/%s"};
|
||||
const char *fl[6] = {"%s:/games/%s/game.iso","%s:/games/%s/sys/boot.bin","%s:/games/%s/sys/bi2.bin",
|
||||
"%s:/games/%s/sys/apploader.img","%s:/games/%s/sys","%s:/games/%s"};
|
||||
char fname[MAX_FAT_PATH];
|
||||
FILE *f;
|
||||
DIR *dir;
|
||||
int i;
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
sprintf(fname, fl[i], discid);
|
||||
sprintf(fname, fl[i], partition, discid);
|
||||
f = fopen((char*)fname, "r");
|
||||
if(f)
|
||||
{
|
||||
@ -123,10 +124,10 @@ void DML_RemoveGame(const char *discid)
|
||||
}
|
||||
}
|
||||
|
||||
bool DML_GameIsInstalled(char *discid)
|
||||
bool DML_GameIsInstalled(char *discid, const char* partition)
|
||||
{
|
||||
char filepath[64];
|
||||
sprintf(filepath, "sd:/games/%s/game.iso", discid);
|
||||
sprintf(filepath, "%s:/games/%s/game.iso", partition, discid);
|
||||
|
||||
gprintf("Filepath on SD: %s\n", filepath);
|
||||
|
||||
|
@ -7,8 +7,8 @@ extern "C"
|
||||
#define GC_H_
|
||||
void set_video_mode(int i);
|
||||
void set_language(u8 lang);
|
||||
void DML_RemoveGame(const char *discid);
|
||||
bool DML_GameIsInstalled(char *discid);
|
||||
void DML_RemoveGame(const char *discid, const char* partition);
|
||||
bool DML_GameIsInstalled(char *discid, const char* partition);
|
||||
#endif //GC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -131,7 +131,7 @@ void CList<dir_discHdr>::GetHeaders(safe_vector<string> pathlist, safe_vector<di
|
||||
if (wbfs || (*itr).rfind(".iso") != string::npos || (*itr).rfind(".ISO") != string::npos)
|
||||
{
|
||||
char* filename = &(*itr)[(*itr).find_last_of('/')+1];
|
||||
if(strcasecmp(filename, "game.iso") == 0 && strncasecmp((*itr).c_str(), "sd:/games/", 10) == 0 )
|
||||
if(strcasecmp(filename, "game.iso") == 0 && strstr((*itr).c_str(), ":/games/") != NULL)
|
||||
{
|
||||
FILE *fp = fopen((*itr).c_str(), "rb");
|
||||
if( fp )
|
||||
|
@ -175,12 +175,12 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
||||
s32 ret = Disc_ReadGCHeader(&gcheader);
|
||||
Asciify2(gcheader.title);
|
||||
|
||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", DeviceName[SD], gcheader.title, (char *)gcheader.id);
|
||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||
makedir((char *)folder);
|
||||
|
||||
if(writeexfiles)
|
||||
{
|
||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", DeviceName[SD], gcheader.title, (char *)gcheader.id);
|
||||
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||
makedir((char *)folder);
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@ s32 GCDump::DumpGame(progress_callback_t spinner, void *spinner_data)
|
||||
__DiscWrite(gamepath, 0x2440, ApploaderSize, spinner, spinner_data);
|
||||
}
|
||||
|
||||
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", DeviceName[SD], gcheader.title, (char *)gcheader.id);
|
||||
snprintf(gamepath, sizeof(gamepath), "%s:/games/%s [%s]/game.iso", gamepartition, gcheader.title, (char *)gcheader.id);
|
||||
|
||||
gprintf("Writing %s\n", gamepath);
|
||||
if(compressed)
|
||||
@ -389,6 +389,6 @@ s32 GCDump::CheckSpace(u32 *needed, bool comp)
|
||||
MEM2_free(FSTBuffer);
|
||||
}
|
||||
*needed = size/0x8000;
|
||||
gprintf("Free space needed on SD: %d bytes (%x blocks)\n", size, size/0x8000);
|
||||
gprintf("Free space needed: %d bytes (%x blocks)\n", size, size/0x8000);
|
||||
return 0;
|
||||
}
|
@ -33,7 +33,7 @@ typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
||||
class GCDump
|
||||
{
|
||||
public:
|
||||
void Init(bool skip, bool comp, bool wexf, bool align, u32 nretry, u32 rsize)
|
||||
void Init(bool skip, bool comp, bool wexf, bool align, u32 nretry, u32 rsize, const char* partition)
|
||||
{
|
||||
skiponerror = skip;
|
||||
compressed = comp;
|
||||
@ -41,6 +41,7 @@ public:
|
||||
force_32k_align = align;
|
||||
gc_nbrretry = nretry;
|
||||
gc_readsize = rsize;
|
||||
gamepartition = partition;
|
||||
gc_skipped = 0;
|
||||
}
|
||||
s32 DumpGame(progress_callback_t spinner, void *spinner_data);
|
||||
@ -50,6 +51,7 @@ private:
|
||||
bool skiponerror;
|
||||
bool compressed;
|
||||
bool writeexfiles;
|
||||
const char* gamepartition;
|
||||
u32 gc_nbrretry;
|
||||
u32 gc_error;
|
||||
u32 gc_retry;
|
||||
|
@ -135,6 +135,7 @@ CMenu::CMenu(CVideo &vid) :
|
||||
m_gamesound_changed = false;
|
||||
m_base_font_size = 0;
|
||||
m_current_view = COVERFLOW_USB;
|
||||
copyGameCubeGame = false;
|
||||
}
|
||||
|
||||
extern "C" { int makedir(char *newdir); }
|
||||
@ -1876,12 +1877,13 @@ bool CMenu::_loadHomebrewList()
|
||||
|
||||
bool CMenu::_loadDmlList()
|
||||
{
|
||||
if(!DeviceHandler::Instance()->IsInserted(SD))
|
||||
currentPartition = m_cfg.getInt("DML", "partition", 0);
|
||||
if(!DeviceHandler::Instance()->IsInserted(currentPartition))
|
||||
return false;
|
||||
|
||||
gprintf("%s\n", DeviceName[SD]);
|
||||
DeviceHandler::Instance()->Open_WBFS(SD);
|
||||
m_gameList.Load(sfmt(DML_DIR, DeviceName[SD]), ".iso", m_cfg.getString("DML", "lastlanguage", "EN").c_str());
|
||||
gprintf("%s\n", DeviceName[currentPartition]);
|
||||
DeviceHandler::Instance()->Open_WBFS(currentPartition);
|
||||
m_gameList.Load(sfmt(DML_DIR, DeviceName[currentPartition]), ".iso", m_cfg.getString("DML", "lastlanguage", "EN").c_str());
|
||||
m_cfg.setString("DML", "lastlanguage", m_loc.getString(m_curLanguage, "gametdb_code", "EN"));
|
||||
m_cfg.save();
|
||||
return m_gameList.size() > 0 ? true : false;
|
||||
|
@ -634,6 +634,7 @@ private:
|
||||
|
||||
private:
|
||||
enum WBFS_OP { WO_ADD_GAME, WO_REMOVE_GAME, WO_FORMAT };
|
||||
bool copyGameCubeGame;
|
||||
typedef std::pair<std::string, u32> FontDesc;
|
||||
typedef std::map<FontDesc, SFont> FontSet;
|
||||
typedef std::map<std::string, STexture> TexSet;
|
||||
@ -931,6 +932,7 @@ private:
|
||||
static void _addDiscProgress(int status, int total, void *user_data);
|
||||
static int _gameInstaller(void *obj);
|
||||
static int _GCgameInstaller(void *obj);
|
||||
static int _GCcopyGame(void *obj);
|
||||
wstringEx _optBoolToString(int b);
|
||||
void _stopSounds(void);
|
||||
|
||||
|
@ -84,14 +84,12 @@ void CMenu::_showConfig(void)
|
||||
_setBg(m_configBg, m_configBg);
|
||||
m_btnMgr.show(m_configLblTitle);
|
||||
m_btnMgr.show(m_configBtnBack);
|
||||
if (m_current_view != COVERFLOW_DML && !m_locked)
|
||||
if (!m_locked)
|
||||
{
|
||||
m_btnMgr.show(m_configLblPartitionName);
|
||||
m_btnMgr.show(m_configLblPartition);
|
||||
m_btnMgr.show(m_configBtnPartitionP);
|
||||
m_btnMgr.show(m_configBtnPartitionM);
|
||||
}
|
||||
if (!m_locked) {
|
||||
m_btnMgr.show(m_configLblDownload);
|
||||
m_btnMgr.show(m_configBtnDownload);
|
||||
}
|
||||
|
@ -161,8 +161,6 @@ void CMenu::_showGameSettings(void)
|
||||
|
||||
if(m_current_view != COVERFLOW_DML)
|
||||
{
|
||||
|
||||
|
||||
m_btnMgr.hide(m_gameSettingsBtnCategoryMain);
|
||||
m_btnMgr.hide(m_gameSettingsLblCategoryMain);
|
||||
|
||||
|
@ -424,6 +424,19 @@ void CMenu::_game(bool launch)
|
||||
else if (launch || m_btnMgr.selected(m_gameBtnPlay) || (!WPadIR_Valid(0) && !WPadIR_Valid(1) && !WPadIR_Valid(2) && !WPadIR_Valid(3) && m_btnMgr.selected((u32)-1)))
|
||||
{
|
||||
_hideGame();
|
||||
|
||||
if(currentPartition != SD && m_current_view == COVERFLOW_DML)
|
||||
{
|
||||
copyGameCubeGame = true;
|
||||
if(!_wbfsOp(CMenu::WO_ADD_GAME))
|
||||
{
|
||||
copyGameCubeGame = false;
|
||||
break;
|
||||
}
|
||||
currentPartition = SD;
|
||||
}
|
||||
|
||||
copyGameCubeGame = false;
|
||||
dir_discHdr *hdr = m_cf.getHdr();
|
||||
|
||||
m_cf.clear();
|
||||
|
@ -156,13 +156,15 @@ void CMenu::LoadView(void)
|
||||
m_cf.applySettings();
|
||||
|
||||
char *mode = (m_current_view == COVERFLOW_CHANNEL && m_cfg.getBool("NAND", "disable", true))
|
||||
? (char *)"NAND" : ((m_current_view == COVERFLOW_DML) ? (char *)"DML" : (char *)DeviceName[currentPartition]);
|
||||
? (char *)"NAND" : (char *)DeviceName[currentPartition];
|
||||
|
||||
for(u8 i = 0; strncmp((const char *)&mode[i], "\0", 1) != 0; i++)
|
||||
mode[i] = toupper(mode[i]);
|
||||
|
||||
m_showtimer=60;
|
||||
m_btnMgr.setText(m_mainLblNotice, (string)mode);
|
||||
char gui_name[20];
|
||||
sprintf(gui_name,"%s [%s]",_domainFromView(),mode);
|
||||
m_btnMgr.setText(m_mainLblNotice, (string)gui_name);
|
||||
m_btnMgr.show(m_mainLblNotice);
|
||||
}
|
||||
|
||||
@ -370,7 +372,7 @@ int CMenu::main(void)
|
||||
{
|
||||
bool block = m_current_view == COVERFLOW_CHANNEL && m_cfg.getBool("NAND", "disable", true);
|
||||
char *partition;
|
||||
if(!block && (m_current_view != COVERFLOW_DML))
|
||||
if(!block)
|
||||
{
|
||||
_showWaitMessage();
|
||||
_hideMain();
|
||||
@ -387,7 +389,7 @@ int CMenu::main(void)
|
||||
(m_current_view == COVERFLOW_CHANNEL && (DeviceHandler::Instance()->GetFSType(currentPartition) != PART_FS_FAT ||
|
||||
(!isD2XnewerThanV6 && DeviceHandler::Instance()->PathToDriveType(m_appDir.c_str()) == currentPartition) ||
|
||||
(!isD2XnewerThanV6 && DeviceHandler::Instance()->PathToDriveType(m_dataDir.c_str()) == currentPartition))) ||
|
||||
(m_current_view == COVERFLOW_HOMEBREW && DeviceHandler::Instance()->GetFSType(currentPartition) == PART_FS_WBFS))
|
||||
((m_current_view == COVERFLOW_HOMEBREW || m_current_view == COVERFLOW_DML) && DeviceHandler::Instance()->GetFSType(currentPartition) == PART_FS_WBFS))
|
||||
{
|
||||
currentPartition = loopNum(currentPartition + 1, (int)USB8);
|
||||
if(limiter > 10) break;
|
||||
@ -399,8 +401,6 @@ int CMenu::main(void)
|
||||
m_cfg.setInt(_domainFromView(), "partition", currentPartition);
|
||||
|
||||
}
|
||||
else if (m_current_view == COVERFLOW_DML)
|
||||
partition = (char *)"DML";
|
||||
else
|
||||
partition = (char *)"NAND";
|
||||
|
||||
@ -410,10 +410,12 @@ int CMenu::main(void)
|
||||
gprintf("Next item: %s\n", partition);
|
||||
|
||||
m_showtimer=60;
|
||||
m_btnMgr.setText(m_mainLblNotice, (string)partition);
|
||||
char gui_name[20];
|
||||
sprintf(gui_name,"%s [%s]",_domainFromView(),partition);
|
||||
m_btnMgr.setText(m_mainLblNotice, (string)gui_name);
|
||||
m_btnMgr.show(m_mainLblNotice);
|
||||
|
||||
if(!block && (m_current_view != COVERFLOW_DML))
|
||||
if(!block)
|
||||
{
|
||||
_loadList();
|
||||
_showMain();
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "lockMutex.hpp"
|
||||
#include "loader/gc_disc.hpp"
|
||||
#include "gc.h"
|
||||
#include "fileOps.h"
|
||||
#include "music/SoundHandler.hpp"
|
||||
#include "channel/nand.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -119,19 +122,21 @@ int CMenu::_GCgameInstaller(void *obj)
|
||||
u32 nretry = m.m_cfg.getUInt("DML", "num_retries", 5);
|
||||
u32 rsize = 32768;
|
||||
|
||||
m_gcdump.Init(skip, comp, wexf, alig, nretry, rsize);
|
||||
m_gcdump.Init(skip, comp, wexf, alig, nretry, rsize,DeviceName[currentPartition]);
|
||||
|
||||
int ret;
|
||||
|
||||
if (!DeviceHandler::Instance()->IsInserted(SD))
|
||||
if (!DeviceHandler::Instance()->IsInserted(currentPartition))
|
||||
{
|
||||
m.m_thrdWorking = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char partition[strlen(DeviceName[currentPartition])+2];
|
||||
sprintf(partition,"%s:/",DeviceName[currentPartition]);
|
||||
struct statvfs stats;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
statvfs("sd:/" , &stats);
|
||||
statvfs(partition , &stats);
|
||||
|
||||
u64 free = (u64)stats.f_frsize * (u64)stats.f_bfree;
|
||||
u32 needed = 0;
|
||||
@ -170,6 +175,45 @@ int CMenu::_GCgameInstaller(void *obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CMenu::_GCcopyGame(void *obj)
|
||||
{
|
||||
CMenu &m = *(CMenu *)obj;
|
||||
char partition[strlen(DeviceName[SD])];
|
||||
sprintf(partition,"%s:/",DeviceName[SD]);
|
||||
if(fsop_GetFreeSpaceKb((char*)DeviceName[SD])<fsop_GetFolderKb(m.m_cf.getHdr()->path))
|
||||
{
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(wfmt(m._fmt("wbfsop11", L"Not enough space: %d blocks needed, %d available"), fsop_GetFolderKb(m.m_cf.getHdr()->path), fsop_GetFreeSpaceKb(partition)), 0.f);
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
m.m_thrdWorking = false;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(L"", 0);
|
||||
char folder[10] = "sd:/games";
|
||||
if (!fsop_DirExist(folder))
|
||||
{
|
||||
fsop_MakeFolder(folder);
|
||||
}
|
||||
char source[64];
|
||||
char target[64];
|
||||
sprintf(source, "%s:/games/%s", DeviceName[currentPartition], m.m_cf.getHdr()->path);
|
||||
sprintf(target, "sd:/games/%s", m.m_cf.getHdr()->path);
|
||||
gprintf("Copying from: \n%s \nto: \n%s\n",source,target);
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
fsop_CopyFolder(source, target, CMenu::_addDiscProgress, obj);
|
||||
LWP_MutexLock(m.m_mutex);
|
||||
m._setThrdMsg(m._t("wbfsop12", L"Game copied"), 1.f);
|
||||
gprintf("Game copied.\n");
|
||||
LWP_MutexUnlock(m.m_mutex);
|
||||
slotLight(true);
|
||||
}
|
||||
m.m_thrdWorking = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
{
|
||||
lwp_t thread = 0;
|
||||
@ -188,10 +232,13 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
switch (op)
|
||||
{
|
||||
case CMenu::WO_ADD_GAME:
|
||||
if(copyGameCubeGame)
|
||||
m_btnMgr.setText(m_wbfsLblDialog, _t("wbfscpydlg", L"If you are sure you want to copy this game to SD, click on Go."));
|
||||
else
|
||||
m_btnMgr.setText(m_wbfsLblDialog, _t("wbfsadddlg", L"Please insert the disc you want to copy, then click on Go."));
|
||||
break;
|
||||
case CMenu::WO_REMOVE_GAME:
|
||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsremdlg", L"To permanently remove the game : %s, click on Go."), m_cf.getTitle().c_str()));
|
||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsremdlg", L"To permanently remove the game: %s, click on Go."), (u8*)m_cf.getTitle().toUTF8().c_str()));
|
||||
break;
|
||||
case CMenu::WO_FORMAT:
|
||||
break;
|
||||
@ -202,7 +249,11 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
{
|
||||
_mainLoopCommon(false, m_thrdWorking);
|
||||
if ((BTN_HOME_PRESSED || BTN_B_PRESSED) && !m_thrdWorking)
|
||||
{
|
||||
if (copyGameCubeGame)
|
||||
return done;
|
||||
break;
|
||||
}
|
||||
else if (BTN_UP_PRESSED)
|
||||
m_btnMgr.up();
|
||||
else if (BTN_DOWN_PRESSED)
|
||||
@ -210,7 +261,11 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
if (BTN_A_PRESSED && !m_thrdWorking)
|
||||
{
|
||||
if (m_btnMgr.selected(m_wbfsBtnBack))
|
||||
{
|
||||
if (copyGameCubeGame)
|
||||
return done;
|
||||
break;
|
||||
}
|
||||
else if (m_btnMgr.selected(m_wbfsBtnGo))
|
||||
{
|
||||
switch (op)
|
||||
@ -222,6 +277,34 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
m_btnMgr.hide(m_wbfsBtnBack);
|
||||
m_btnMgr.show(m_wbfsLblMessage);
|
||||
m_btnMgr.setText(m_wbfsLblMessage, L"");
|
||||
if (copyGameCubeGame)
|
||||
{
|
||||
char gcfolder[64];
|
||||
char* title = (char *)m_cf.getTitle().toUTF8().c_str();
|
||||
char* gameid = (char *)m_cf.getHdr()->hdr.id;
|
||||
sprintf(gcfolder, "%s [%s]", title, gameid);
|
||||
if (DML_GameIsInstalled(gameid, DeviceName[SD]) || DML_GameIsInstalled(gcfolder, DeviceName[SD]))
|
||||
{
|
||||
error(_t("wbfsoperr4", L"Game already installed"));
|
||||
out = true;
|
||||
break;
|
||||
}
|
||||
cfPos = string(gameid);
|
||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop10", L"Copying [%s] %s..."), (u8*)gameid, (u8*)m_cf.getTitle().toUTF8().c_str()));
|
||||
done = true;
|
||||
m_thrdWorking = true;
|
||||
m_thrdProgress = 0.f;
|
||||
m_thrdMessageAdded = false;
|
||||
m_cf.stopCoverLoader();
|
||||
_stopSounds();
|
||||
MusicPlayer::DestroyInstance();
|
||||
SoundHandler::DestroyInstance();
|
||||
soundDeinit();
|
||||
Nand::Instance()->Disable_Emu();
|
||||
Nand::DestroyInstance();
|
||||
LWP_CreateThread(&thread, (void *(*)(void *))CMenu::_GCcopyGame, (void *)this, 0, 8 * 1024, 64);
|
||||
break;
|
||||
}
|
||||
Disc_SetUSB(NULL);
|
||||
if (Disc_Wait() < 0)
|
||||
{
|
||||
@ -260,7 +343,7 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
|
||||
char gcfolder[64];
|
||||
sprintf(gcfolder, "%s [%s]", gcheader.title, (char *)gcheader.id);
|
||||
if (_searchGamesByID((const char *) gcheader.id).size() != 0 || DML_GameIsInstalled((char *)gcheader.id) || DML_GameIsInstalled(gcfolder))
|
||||
if (_searchGamesByID((const char *) gcheader.id).size() != 0 || DML_GameIsInstalled((char *)gcheader.id, DeviceName[currentPartition]) || DML_GameIsInstalled(gcfolder, DeviceName[currentPartition]))
|
||||
{
|
||||
error(_t("wbfsoperr4", L"Game already installed"));
|
||||
out = true;
|
||||
@ -286,7 +369,7 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
if(m_current_view == COVERFLOW_USB)
|
||||
WBFS_RemoveGame((u8 *)m_cf.getId().c_str(), (char *) m_cf.getHdr()->path);
|
||||
else
|
||||
DML_RemoveGame(m_cf.getHdr()->path);
|
||||
DML_RemoveGame(m_cf.getHdr()->path, DeviceName[currentPartition]);
|
||||
if(m_cfg.getBool("GENERAL", "delete_cover_and_game", true))
|
||||
RemoveCover((char *)m_cf.getId().c_str());
|
||||
m_btnMgr.show(m_wbfsPBar);
|
||||
@ -319,7 +402,7 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
}
|
||||
}
|
||||
_hideWBFS();
|
||||
if (done && (op == CMenu::WO_REMOVE_GAME || op == CMenu::WO_ADD_GAME))
|
||||
if (done && !copyGameCubeGame && (op == CMenu::WO_REMOVE_GAME || op == CMenu::WO_ADD_GAME))
|
||||
{
|
||||
m_gameList.SetLanguage(m_loc.getString(m_curLanguage, "gametdb_code", "EN").c_str());
|
||||
if( upd_dml )
|
||||
|
Loading…
Reference in New Issue
Block a user