NAND Emulation:

- Fixed Nand Emulation from SD-card.
- Fixed "CheckSave" functions.
- Fixed feature to flash a save file from emulated NAND back to real NAND.
- Some minor code cleanups and bug fixes.

neek2o: (neek2o r93+ only)
- Fixed return to channel function for titles on emulated NAND
- Added an option in wiiflow.ini: launchwiiflow in "NEEK2O" domain
  If this option is set to "no" the "exit to" option in home menu 
  will launch neek2o SM instead of the "DWFA" channel.
- If the return to channel option is set.. neek2o will return to 
  that specific title if that title exists on the emulated nand, even
  if the title was launched from real NAND.
This commit is contained in:
overjoy.psm 2012-09-09 22:38:42 +00:00
parent 4e345b651f
commit 37787dbcd9
17 changed files with 118 additions and 77 deletions

View File

@ -119,10 +119,13 @@ s32 Nand::Nand_Unmount(NandDevice *Device)
s32 Nand::Nand_Enable(NandDevice *Device)
{
gprintf("Enabling NAND Emulator\n");
gprintf("Enabling NAND Emulator...");
s32 fd = IOS_Open("/dev/fs", 0);
if(fd < 0)
{
gprintf(" failed!\n");
return fd;
}
int NandPathlen = strlen(NandPath) + 1;
@ -138,6 +141,7 @@ s32 Nand::Nand_Enable(NandDevice *Device)
s32 ret = IOS_Ioctlv(fd, 100, 2, 0, vector);
IOS_Close(fd);
gprintf(" %s!\n", ret < 0 ? "failed" : "OK");
return ret;
}
@ -192,6 +196,11 @@ s32 Nand::Disable_Emu()
return 0;
}
bool Nand::EmulationEnabled(void)
{
return emu_enabled;
}
void Nand::Set_NandPath(string path)
{
if(isalnum(*(path.begin())))

View File

@ -61,6 +61,7 @@ public:
void Init(string path, u32 partition, bool disable = false);
s32 Enable_Emu();
s32 Disable_Emu();
bool EmulationEnabled(void);
void Set_Partition(u32 partition) { Partition = partition; };
void Set_FullMode(bool fullmode) { FullMode = fullmode ? 0x100 : 0; };

View File

@ -429,3 +429,11 @@ bool DeviceHandler::UsablePartitionMounted()
}
return false;
}
bool DeviceHandler::PartitionUsableForNandEmu(int Partition)
{
if(IsInserted(Partition) && GetFSType(Partition) == PART_FS_FAT)
return true;
return false;
}

View File

@ -86,6 +86,7 @@ class DeviceHandler
bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; }
bool USB1_Inserted() { if(usb1) return usb1->IsInserted(); return false; }
bool UsablePartitionMounted();
bool PartitionUsableForNandEmu(int Partition);
void WaitForDevice(const DISC_INTERFACE *Handle);
void UnMountSD() { if(sd) delete sd; sd = NULL; }

View File

@ -123,9 +123,8 @@ void CachedList::LoadChannels(string path, u32 channelType, string m_lastLanguag
//gprintf("%s\n", m_database.c_str());
struct stat filestat, cache;
string newpath = sfmt("%s%s", path.c_str(), "title");
if(stat(newpath.c_str(), &filestat) == -1) return;
/*** Removed that stupid check overhere! ***/
/*** Will replace it soon with something better!! ***/
m_update = force_update[COVERFLOW_CHANNEL] || m_lastLanguage != m_curLanguage || stat(m_database.c_str(), &cache) == -1 || filestat.st_mtime > cache.st_mtime;
}

View File

@ -413,6 +413,7 @@ void CList<dir_discHdr>::GetChannels(vector<dir_discHdr> &headerlist, string set
}
u32 count = m_channels.Count();
gprintf("PFFF: Channel count: %d\n", count);
headerlist.reserve(count);

View File

@ -77,7 +77,7 @@ bool Load_Neek2o_Kernel()
return false;
}
s32 Launch_nk(u64 TitleID, const char *nandpath)
s32 Launch_nk(u64 TitleID, const char *nandpath, u64 ReturnTo)
{
if(neek2o())
{
@ -93,7 +93,13 @@ s32 Launch_nk(u64 TitleID, const char *nandpath)
return 0;
memset(MC, 0, sizeof(memcfg));
MC->magic = 0x666c6f77;
if(TitleID)
MC->titleid = TitleID;
if(ReturnTo)
{
MC->returnto = ReturnTo;
MC->config |= NCON_EXT_RETURN_TO;
}
if(nandpath != NULL)
{

View File

@ -5,6 +5,8 @@ enum ExtNANDCfg
{
NCON_EXT_DI_PATH = (1<<0),
NCON_EXT_NAND_PATH = (1<<1),
NCON_HIDE_EXT_PATH = (1<<2),
NCON_EXT_RETURN_TO = (1<<3),
};
typedef struct _memcfg
@ -12,10 +14,9 @@ typedef struct _memcfg
u32 magic;
u64 titleid;
u32 config;
u64 returnto;
u32 paddinga;
u32 paddingb;
u32 paddingc;
u32 paddingd;
char dipath[256];
char nandpath[256];
} memcfg;
@ -24,7 +25,7 @@ typedef struct _memcfg
extern "C" {
#endif /* __cplusplus */
s32 Launch_nk(u64 TitleID, const char *nandpath);
s32 Launch_nk(u64 TitleID, const char *nandpath, u64 ReturnTo);
bool Load_Neek2o_Kernel();
bool neek2o(void);

View File

@ -108,8 +108,10 @@ void Sys_Exit(void)
/* Shutdown Inputs */
Close_Inputs();
WII_Initialize();
if(ExitOption == EXIT_TO_NEEK2O)
Launch_nk(0x1000144574641LL, NeekPath);
if(ExitOption == EXIT_TO_WFNK2O)
Launch_nk(0x1000144574641LL, NeekPath, 0);
else if(ExitOption == EXIT_TO_SMNK2O)
Launch_nk(0, NeekPath, 0);
else if(ExitOption == EXIT_TO_BOOTMII)
IOS_ReloadIOS(0xfe);
else if(ExitOption == EXIT_TO_HBC)

View File

@ -22,7 +22,8 @@ enum
EXIT_TO_PRIILOADER,
EXIT_TO_DISABLE,
EXIT_TO_BOOTMII,
EXIT_TO_NEEK2O,
EXIT_TO_WFNK2O,
EXIT_TO_SMNK2O,
BUTTON_CALLBACK,
};

View File

@ -275,7 +275,7 @@ void CMenu::init(void)
m_DMLgameDir = sfmt("%%s:/%s", m_cfg.getString("DML", "dir_usb_games", "games").c_str());
m_cfg.getString("NAND", "path", "");
m_cfg.getInt("NAND", "partition", 0);
m_cfg.getInt("NAND", "partition", 1);
m_cfg.getBool("NAND", "disable", true);
_installed_cios.clear();
@ -2052,13 +2052,16 @@ const wstringEx CMenu::_fmt(const char *key, const wchar_t *def)
bool CMenu::_loadChannelList(void)
{
string emuPath;
m_partRequest = m_cfg.getInt("NAND", "partition", 0);
int emuPartition = _FindEmuPart(&emuPath, m_partRequest, false);
int emuPartition = -1;
bool disable_emu = (m_cfg.getBool("NAND", "disable", true) || neek2o());
static bool last_emu_state = disable_emu;
if(!disable_emu)
{
m_partRequest = m_cfg.getInt("NAND", "partition", 1);
emuPartition = _FindEmuPart(&emuPath, m_partRequest, false);
if(emuPartition < 0)
emuPartition = _FindEmuPart(&emuPath, m_partRequest, true);
@ -2066,13 +2069,16 @@ bool CMenu::_loadChannelList(void)
return false;
else
currentPartition = emuPartition;
}
static u8 lastPartition = currentPartition;
static bool first = true;
static bool failed = false;
bool changed = lastPartition != currentPartition || last_emu_state != disable_emu || first || failed;
bool changed = lastPartition != currentPartition || last_emu_state != disable_emu || first;
if(changed)
UpdateCache(COVERFLOW_CHANNEL);
gprintf("%s, which is %s\n", disable_emu ? "NAND" : DeviceName[emuPartition], changed ? "refreshing." : "cached.");
@ -2096,19 +2102,15 @@ bool CMenu::_loadChannelList(void)
Nand::Instance()->Init(emuPath.c_str(), currentPartition, disable_emu);
if(Nand::Instance()->Enable_Emu() < 0)
{
Nand::Instance()->Disable_Emu();
failed = true;
}
else
failed = false;
gprintf("nandpath = %s\n", nandpath.c_str());
gprintf("Using path: \"%s\" for NAND emulation\n", nandpath.c_str());
}
if(!DeviceHandler::Instance()->IsInserted(currentPartition))
DeviceHandler::Instance()->Mount(currentPartition);
if(!failed)
if(Nand::Instance()->EmulationEnabled() || disable_emu)
{
m_gameList.LoadChannels(disable_emu ? "" : nandpath, 0, m_cfg.getString("NAND", "lastlanguage", "EN").c_str());
m_cfg.setString("NAND", "lastlanguage", m_loc.getString(m_curLanguage, "gametdb_code", "EN"));

View File

@ -1083,13 +1083,19 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
error(_t("errneek1", L"Cannot launch neek2o. Verify your neek2o setup"));
Sys_Exit();
}
int rtrnID = 0;
if(rtrn != NULL && strlen(rtrn) == 4)
rtrnID = rtrn[0] << 24 | rtrn[1] << 16 | rtrn[2] << 8 | rtrn[3];
ShutdownBeforeExit();
Launch_nk(gameTitle, emuPath.size() > 1 ? emuPath.c_str() : NULL);
Launch_nk(gameTitle, emuPath.size() > 1 ? emuPath.c_str() : NULL, rtrnID ? (((u64)(0x00010001) << 32) | (rtrnID & 0xFFFFFFFF)) : rtrnID);
}
if(!forwarder || neek2o())
{
if(!emu_disabled)
{
DeviceHandler::Instance()->UnMount(emuPartition);
Nand::Instance()->Init(emuPath.c_str(), emuPartition, false);
Nand::Instance()->Enable_Emu();
}
@ -1099,7 +1105,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
if(_loadIOS(gameIOS, userIOS, id) == LOAD_IOS_FAILED)
Sys_Exit();
}
if(CurrentIOS.Type == IOS_TYPE_D2X && rtrn != NULL && strlen(rtrn) == 4)
if((CurrentIOS.Type == IOS_TYPE_D2X || neek2o()) && rtrn != NULL && strlen(rtrn) == 4)
{
int rtrnID = rtrn[0] << 24 | rtrn[1] << 16 | rtrn[2] << 8 | rtrn[3];
@ -1273,6 +1279,11 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
Nand::Instance()->CreatePath("%s:/wiiflow/nandemu", DeviceName[emuPartition]);
}
}
m_cfg.setInt("GAMES", "savepartition", emuPartition);
m_cfg.setString("GAMES", "savepath", emuPath);
m_cfg.save();
char basepath[64];
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[emuPartition], emuPath.c_str());

View File

@ -146,7 +146,13 @@ bool CMenu::_ExitTo(void)
exitHandler(PRIILOADER_DEF);
}
else
exitHandler(EXIT_TO_BOOTMII);
{
bool nkWiiflow = m_cfg.getBool("NEEK2O", "launchwiiflow", true);
if(nkWiiflow)
exitHandler(EXIT_TO_WFNK2O);
else
exitHandler(EXIT_TO_SMNK2O);
}
break;
}
}

View File

@ -822,7 +822,7 @@ int CMenu::main(void)
_launchHomebrew(fmt("%s/boot.dol", m_appDir.c_str()), m_homebrewArgs);
return 0;
}
else if(Sys_GetExitTo() == EXIT_TO_NEEK2O)
else if(Sys_GetExitTo() == EXIT_TO_SMNK2O || Sys_GetExitTo() == EXIT_TO_WFNK2O)
{
string emuPath;
_FindEmuPart(&emuPath, m_cfg.getInt("NAND", "partition", 0), false);

View File

@ -61,14 +61,14 @@ static bool _saveExists(const char *path)
bool CMenu::_TestEmuNand(int epart, const char *path, bool indept)
{
bool haveValidENand = true;
char basepath[64];
char testpath[MAX_FAT_PATH];
snprintf(basepath, sizeof(basepath), "%s:%s", DeviceName[epart], path);
DIR *d;
d = opendir(basepath);
if(!d)
haveValidENand = false;
return false;
else
closedir(d);
@ -77,29 +77,22 @@ bool CMenu::_TestEmuNand(int epart, const char *path, bool indept)
// Check Wiimotes && Region
snprintf(testpath, sizeof(testpath), "%s:%s/shared2/sys/SYSCONF", DeviceName[epart], path);
if(!fsop_FileExist(testpath))
{
//gprintf("Nandcheck: SYSCONF not found\n");
haveValidENand = false;
}
return false;
snprintf(testpath, sizeof(testpath), "%s:%s/title/00000001/00000002/data/setting.txt", DeviceName[epart], path);
if(!fsop_FileExist(testpath))
{
//gprintf("Nandcheck: setting.txt not found\n");
haveValidENand = false;
}
return false;
// Check Mii's
snprintf(testpath, sizeof(testpath), "%s:%s/shared2/menu/FaceLib/RFL_DB.dat", DeviceName[epart], path);
if(!fsop_FileExist(testpath))
{
//gprintf("Nandcheck: Mii's not found\n");
haveValidENand = false;
return false;
}
}
return haveValidENand;
return true;
}
int CMenu::_FindEmuPart(string *emuPath, int part, bool searchvalid)
{
Nand::Instance()->Disable_Emu();
int emuPartition = -1;
string tmpPath;
if(m_current_view == COVERFLOW_CHANNEL)
@ -125,24 +118,25 @@ int CMenu::_FindEmuPart(string *emuPath, int part, bool searchvalid)
}
}
if(_TestEmuNand(emuPartition, tmpPath.c_str(), true) && DeviceHandler::Instance()->IsInserted(emuPartition) && DeviceHandler::Instance()->GetFSType(emuPartition) == PART_FS_FAT)
if(!DeviceHandler::Instance()->IsInserted(emuPartition))
DeviceHandler::Instance()->Mount(emuPartition);
if(_TestEmuNand(emuPartition, tmpPath.c_str(), true) && DeviceHandler::Instance()->PartitionUsableForNandEmu(emuPartition))
{
*emuPath = tmpPath;
return emuPartition;
}
else
{
emuPartition = part;
bool fllscn = emuPartition == -1;
for(u8 i = emuPartition; i <= USB8; ++i)
for(u8 i = part; i <= USB8; ++i)
{
if(!DeviceHandler::Instance()->IsInserted(emuPartition) || DeviceHandler::Instance()->GetFSType(emuPartition) != PART_FS_FAT)
{
emuPartition++;
if(!DeviceHandler::Instance()->IsInserted(i))
DeviceHandler::Instance()->Mount(i);
if(!DeviceHandler::Instance()->PartitionUsableForNandEmu(i))
continue;
}
else
{
if(_TestEmuNand(i, tmpPath.c_str(), true) || searchvalid)
{
if(m_current_view == COVERFLOW_CHANNEL)
@ -155,11 +149,10 @@ int CMenu::_FindEmuPart(string *emuPath, int part, bool searchvalid)
return i;
}
}
if(i == USB8 && !fllscn)
{
i = 0;
i = -1;
fllscn = true;
}
}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="false"></e><e p="Wiiflow\wii" x="false"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\portlibs" x="false"></e></ViewState></pd>
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="true"></e><e p="Wiiflow\source\network" x="false"></e><e p="Wiiflow\source\channel" x="false"></e><e p="Wiiflow\source\menu" x="true"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\portlibs" x="false"></e><e p="Wiiflow\source\banner" x="false"></e><e p="Wiiflow\source\cheats" x="false"></e><e p="Wiiflow\source\config" x="false"></e><e p="Wiiflow\source\devicemounter" x="false"></e><e p="Wiiflow\source\fileOps" x="false"></e><e p="Wiiflow\source\gc" x="false"></e><e p="Wiiflow\source\gecko" x="false"></e><e p="Wiiflow\source\gui" x="false"></e><e p="Wiiflow\source\homebrew" x="false"></e><e p="Wiiflow\source\libwbfs" x="false"></e><e p="Wiiflow\source\list" x="false"></e><e p="Wiiflow\source\loader" x="true"></e><e p="Wiiflow\source\memory" x="false"></e><e p="Wiiflow\source\music" x="false"></e><e p="Wiiflow\source\plugin" x="false"></e><e p="Wiiflow\source\unzip" x="false"></e><e p="Wiiflow\source\wstringEx" x="false"></e><e p="Wiiflow\wii" x="false"></e></ViewState></pd>