* Fixed downloading wiitdb on new install

* Fixed creating game save path for EmuNAND channels if 
  EmuNAND chan path is different than EmuNAND save path.
* Prevent deleted channels to be displayed if tmd still exists
* Moved gameconfig.txt loading outside of Ocarina function
* Changed return values in game booter
* Nintendont: check Kenobiwii.bin only on Rev < 336
This commit is contained in:
cyan06 2015-06-28 14:13:52 +00:00
parent 9af7ee1010
commit b9139a4242
12 changed files with 138 additions and 82 deletions

View File

@ -2,8 +2,8 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>3.0 r1246</version> <version>3.0 r1247</version>
<release_date>20150510135131</release_date> <release_date>20150613113624</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>
<arg>--ios=250</arg> <arg>--ios=250</arg>

View File

@ -448,6 +448,49 @@ bool Channels::Identify(const u64 &titleid, u8 *tmdBuffer, u32 tmdSize)
return ret < 0 ? false : true; return ret < 0 ? false : true;
} }
bool Channels::emuExists(char *tmdpath)
{
u8 *buffer = NULL;
u32 size = 0;
if(LoadFileToMem(tmdpath, &buffer, &size) < 0)
return false;
signed_blob *s_tmd = (signed_blob *) buffer;
u32 i;
tmd *titleTmd = (tmd *) SIGNATURE_PAYLOAD(s_tmd);
for (i = 0; i < titleTmd->num_contents; i++)
if (!titleTmd->contents[i].index)
break;
if(i == titleTmd->num_contents)
{
free(buffer);
return false;
}
u32 cid = titleTmd->contents[i].cid;
free(buffer);
char *ptr = strrchr(tmdpath, '/');
if(!ptr)
return false;
//! tmdpath has length of 1024
snprintf(ptr+1, 1024-(ptr+1-tmdpath), "%08x.app", cid);
FILE *f = fopen(tmdpath, "rb");
if(!f)
return false;
fclose(f);
return true;
}
bool Channels::ParseTitleDir(char *path, int language) bool Channels::ParseTitleDir(char *path, int language)
{ {
if(!path) if(!path)
@ -485,6 +528,10 @@ bool Channels::ParseTitleDir(char *path, int language)
if(stat(path, &st) != 0) if(stat(path, &st) != 0)
continue; continue;
// check if content in tmd exists
if(!emuExists(path))
continue;
u32 tidLow = strtoul(dirent->d_name, NULL, 16); u32 tidLow = strtoul(dirent->d_name, NULL, 16);
char id[5]; char id[5];
memset(id, 0, sizeof(id)); memset(id, 0, sizeof(id));

View File

@ -52,6 +52,7 @@ private:
static Channels *instance; static Channels *instance;
static bool Identify(const u64 &titleid, u8 *tmdBuffer, u32 tmdSize); static bool Identify(const u64 &titleid, u8 *tmdBuffer, u32 tmdSize);
bool emuExists(char *tmdpath);
void InternalGetNandChannelList(u32 type); void InternalGetNandChannelList(u32 type);
bool ParseTitleDir(char *path, int language); bool ParseTitleDir(char *path, int language);

View File

@ -45,7 +45,7 @@ StartUpProcess::StartUpProcess()
messageTxt->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE); messageTxt->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
messageTxt->SetPosition(screenwidth/2, screenheight/2+60); messageTxt->SetPosition(screenwidth/2, screenheight/2+60);
versionTxt = new GuiText(" ", 15, (GXColor) {255, 255, 255, 255}); versionTxt = new GuiText(" ", 18, (GXColor) {255, 255, 255, 255});
versionTxt->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); versionTxt->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
versionTxt->SetPosition(20, screenheight-20); versionTxt->SetPosition(20, screenheight-20);

View File

@ -343,13 +343,13 @@ int UpdateApp()
{ {
if (!IsNetworkInit() && !NetworkInitPrompt()) if (!IsNetworkInit() && !NetworkInitPrompt())
{ {
WindowPrompt(tr("Error !"), tr("Could not initialize network!"), tr("OK")); WindowPrompt(tr("Error:"), tr("Could not initialize network!"), tr("OK"));
return -1; return -1;
} }
if (!CreateSubfolder(Settings.update_path)) if (!CreateSubfolder(Settings.update_path))
{ {
WindowPrompt(tr("Error !"), tr("Can't create directory"), tr("OK")); WindowPrompt(tr("Error:"), tr("Can't create directory"), tr("OK"));
return -1; return -1;
} }

View File

@ -320,15 +320,16 @@ void app_pokevalues()
i += *(gameconf + i) + 4; i += *(gameconf + i) + 4;
continue; continue;
} }
if (codeaddr2 == 0) codeaddr2 = codeaddr + *(gameconf + i); if (codeaddr2 == 0)
codeaddr2 = codeaddr + *(gameconf + i);
addrfound = NULL; addrfound = NULL;
while (codeaddr <= (codeaddr2 - *(gameconf + i))) while (codeaddr <= (codeaddr2 - *(gameconf + i)))
{ {
if (memcmp(codeaddr, gameconf + i + 1, (*(gameconf + i)) * 4) == 0) if (memcmp(codeaddr, gameconf + i + 1, (*(gameconf + i)) * 4) == 0)
{ {
*(codeaddr + ((*(gameconf + i + *(gameconf + i) + 3)) / 4)) = *(gameconf + i + *(gameconf + i) *(codeaddr + ((*(gameconf + i + *(gameconf + i) + 3)) / 4)) = *(gameconf + i + *(gameconf + i) + 4);
+ 4); if (addrfound == NULL)
if (addrfound == NULL) addrfound = codeaddr; addrfound = codeaddr;
} }
codeaddr++; codeaddr++;
} }
@ -406,7 +407,8 @@ static void app_loadgameconfig()
else if (tempgameconf[i] == ' ') else if (tempgameconf[i] == ' ')
break; break;
else i++; else i++;
if (parsebufpos == 8) break; if (parsebufpos == 8)
break;
} }
parsebuffer[parsebufpos] = 0; parsebuffer[parsebufpos] = 0;
if (strncasecmp("DEFAULT", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 7) if (strncasecmp("DEFAULT", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 7)
@ -430,19 +432,18 @@ static void app_loadgameconfig()
parsebufpos = 0; parsebufpos = 0;
while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13))
{ {
if (tempgameconf[i] != 0 && tempgameconf[i] != ' ' && tempgameconf[i] != '(' && tempgameconf[i] if (tempgameconf[i] != 0 && tempgameconf[i] != ' ' && tempgameconf[i] != '(' && tempgameconf[i] != ':')
!= ':')
parsebuffer[parsebufpos++] = tempgameconf[i++]; parsebuffer[parsebufpos++] = tempgameconf[i++];
else if (tempgameconf[i] == ' ' || tempgameconf[i] == '(' || tempgameconf[i] == ':') else if (tempgameconf[i] == ' ' || tempgameconf[i] == '(' || tempgameconf[i] == ':')
break; break;
else i++; else i++;
if (parsebufpos == 17) break; if (parsebufpos == 17)
break;
} }
parsebuffer[parsebufpos] = 0; parsebuffer[parsebufpos] = 0;
//if (!autobootcheck) //if (!autobootcheck)
{ {
if (strncasecmp("codeliststart", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) if (strncasecmp("codeliststart", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 13)
== 13)
{ {
sscanf((char *) (tempgameconf + i), " = %x", (unsigned int *) &codelist); sscanf((char *) (tempgameconf + i), " = %x", (unsigned int *) &codelist);
} }
@ -468,8 +469,7 @@ static void app_loadgameconfig()
} }
if (strncasecmp("pokeifequal", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11) if (strncasecmp("pokeifequal", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 11)
{ {
ret = sscanf((char *) (tempgameconf + i), "( %x , %x , %x , %x", &codeaddr, &codeval, ret = sscanf((char *) (tempgameconf + i), "( %x , %x , %x , %x", &codeaddr, &codeval, &codeaddr2, &codeval2);
&codeaddr2, &codeval2);
if (ret == 4) if (ret == 4)
{ {
*(gameconf + (gameconfsize / 4)) = 0; *(gameconf + (gameconfsize / 4)) = 0;
@ -485,8 +485,7 @@ static void app_loadgameconfig()
DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20); DCFlushRange((void *) (gameconf + (gameconfsize / 4) - 5), 20);
} }
} }
if (strncasecmp("searchandpoke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) if (strncasecmp("searchandpoke", parsebuffer, strlen(parsebuffer)) == 0 && strlen(parsebuffer) == 13)
== 13)
{ {
ret = sscanf((char *) (tempgameconf + i), "( %x%n", &codeval, &tempoffset); ret = sscanf((char *) (tempgameconf + i), "( %x%n", &codeval, &tempoffset);
if (ret == 1) if (ret == 1)
@ -502,8 +501,7 @@ static void app_loadgameconfig()
ret = sscanf((char *) (tempgameconf + i), " %x%n", &codeval, &tempoffset); ret = sscanf((char *) (tempgameconf + i), " %x%n", &codeval, &tempoffset);
} }
*(gameconf + (gameconfsize / 4) - temp - 1) = temp; *(gameconf + (gameconfsize / 4) - temp - 1) = temp;
ret = sscanf((char *) (tempgameconf + i), " , %x , %x , %x , %x", &codeaddr, &codeaddr2, ret = sscanf((char *) (tempgameconf + i), " , %x , %x , %x , %x", &codeaddr, &codeaddr2, &codeoffset, &codeval2);
&codeoffset, &codeval2);
if (ret == 4) if (ret == 4)
{ {
*(gameconf + (gameconfsize / 4)) = codeaddr; *(gameconf + (gameconfsize / 4)) = codeaddr;
@ -525,10 +523,12 @@ static void app_loadgameconfig()
{ {
while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13)) while ((i != tempgameconfsize) && (tempgameconf[i] != 10 && tempgameconf[i] != 13))
i++; i++;
if (i != tempgameconfsize) i++; if (i != tempgameconfsize)
i++;
} }
} }
if (i != tempgameconfsize) while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0)) if (i != tempgameconfsize)
while ((tempgameconf[i] != 10 && tempgameconf[i] != 13) && (i != 0))
i--; i--;
} }
} }
@ -672,7 +672,7 @@ void load_handler(u32 hooktype, u32 debugger, u32 pauseAtStart)
} }
} }
static int LoadGameConfig(const char *CheatFilepath) int LoadGameConfig(const char *CheatFilepath)
{ {
int filesize = 0; int filesize = 0;
tempgameconf = (u8 *) defaultgameconfig; tempgameconf = (u8 *) defaultgameconfig;
@ -774,7 +774,7 @@ int ocarina_load_code(const char *CheatFilepath, u8 *gameid)
gprintf("Ocarina: Codes found.\n"); gprintf("Ocarina: Codes found.\n");
LoadGameConfig(CheatFilepath); //LoadGameConfig(CheatFilepath);
return code_size; return code_size;
} }

View File

@ -35,6 +35,7 @@ void load_handler(u32 hooktype, u32 debugger, u32 pauseAtStart);
void langpatcher(void *addr, u32 len, u8 languageChoice); void langpatcher(void *addr, u32 len, u8 languageChoice);
void vidolpatcher(void *addr, u32 len); void vidolpatcher(void *addr, u32 len);
void patchdebug(void *addr, u32 len); void patchdebug(void *addr, u32 len);
int LoadGameConfig(const char *CheatFilepath);
int ocarina_load_code(const char *CheatFilepath, u8 *gameid); int ocarina_load_code(const char *CheatFilepath, u8 *gameid);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -797,9 +797,12 @@ void GameWindow::BootGame(struct discHdr *header)
GameStatistics.Save(); GameStatistics.Save();
//Just calling that shuts down everything and starts game //Just calling that shuts down everything and starts game
GameBooter::BootGame(header); int ret = GameBooter::BootGame(header);
//If the launch is canceled, reduce playCount //If the launch is canceled, reduce playCount
if(ret == -1)
{
GameStatistics.SetPlayCount(header->id, GameStatistics.GetPlayCount(header->id)-1); GameStatistics.SetPlayCount(header->id, GameStatistics.GetPlayCount(header->id)-1);
GameStatistics.Save(); GameStatistics.Save();
}
} }

View File

@ -59,7 +59,7 @@ void CSettings::SetDefault()
snprintf(covers2d_path, sizeof(covers2d_path), "%simages/2D/", ConfigPath); snprintf(covers2d_path, sizeof(covers2d_path), "%simages/2D/", ConfigPath);
snprintf(coversFull_path, sizeof(coversFull_path), "%simages/full/", ConfigPath); snprintf(coversFull_path, sizeof(coversFull_path), "%simages/full/", ConfigPath);
snprintf(disc_path, sizeof(disc_path), "%simages/disc/", ConfigPath); snprintf(disc_path, sizeof(disc_path), "%simages/disc/", ConfigPath);
snprintf(titlestxt_path, sizeof(titlestxt_path), "%stitles", ConfigPath); snprintf(titlestxt_path, sizeof(titlestxt_path), "%stitles/", ConfigPath);
snprintf(languagefiles_path, sizeof(languagefiles_path), "%slanguage/", ConfigPath); snprintf(languagefiles_path, sizeof(languagefiles_path), "%slanguage/", ConfigPath);
snprintf(update_path, sizeof(update_path), "%s/apps/usbloader_gx/", BootDevice); snprintf(update_path, sizeof(update_path), "%s/apps/usbloader_gx/", BootDevice);
snprintf(BNRCachePath, sizeof(BNRCachePath), "%s/apps/usbloader_gx/cache_bnr/", BootDevice); snprintf(BNRCachePath, sizeof(BNRCachePath), "%s/apps/usbloader_gx/cache_bnr/", BootDevice);

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2012-2014 Cyan * Copyright (C) 2012-2015 Cyan
* Copyright (C) 2011 Dimok * Copyright (C) 2011 Dimok
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -156,7 +156,7 @@ void GameBooter::SetupNandEmu(u8 NandEmuMode, const char *NandEmuPath, struct di
int partition = -1; int partition = -1;
//! Create save game path and title.tmd for not existing saves //! Create save game path and title.tmd for not existing saves
CreateSavePath(&gameHeader); CreateSavePath(&gameHeader, NandEmuPath);
gprintf("Enabling %s Nand Emulation on: %s\n", NandEmuMode == 2 ? "Full" : "Partial" , NandEmuPath); gprintf("Enabling %s Nand Emulation on: %s\n", NandEmuMode == 2 ? "Full" : "Partial" , NandEmuPath);
Set_FullMode(NandEmuMode == 2); Set_FullMode(NandEmuMode == 2);
@ -287,10 +287,6 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
: 0; //! Real nand title : 0; //! Real nand title
NandEmuPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str(); NandEmuPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str();
} }
if(ocarinaChoice && Hooktype == OFF)
Hooktype = 1;
//! Prepare alternate dol settings //! Prepare alternate dol settings
SetupAltDOL(gameHeader.id, alternatedol, alternatedoloffset); SetupAltDOL(gameHeader.id, alternatedol, alternatedoloffset);
@ -321,10 +317,18 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
//! Load wip codes //! Load wip codes
load_wip_code(gameHeader.id); load_wip_code(gameHeader.id);
// force hooktype if not selected but Ocarina is enabled
if(ocarinaChoice && Hooktype == OFF)
Hooktype = 1;
//! Load Ocarina codes //! Load Ocarina codes
if (ocarinaChoice) if (ocarinaChoice)
ocarina_load_code(Settings.Cheatcodespath, gameHeader.id); ocarina_load_code(Settings.Cheatcodespath, gameHeader.id);
//! Load gameconfig.txt even if ocarina disabled
if(Hooktype)
LoadGameConfig(Settings.Cheatcodespath);
//! Setup NAND emulation //! Setup NAND emulation
SetupNandEmu(NandEmuMode, NandEmuPath, gameHeader); SetupNandEmu(NandEmuMode, NandEmuPath, gameHeader);
@ -452,7 +456,7 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
if(strncmp(Settings.GameCubePath, "sd", 2) == 0 || strncmp(DeviceHandler::PathToFSName(Settings.GameCubePath), "FAT", 3) != 0) if(strncmp(Settings.GameCubePath, "sd", 2) == 0 || strncmp(DeviceHandler::PathToFSName(Settings.GameCubePath), "FAT", 3) != 0)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK"));
return 0; return -1;
} }
// Check current game location // Check current game location
@ -460,7 +464,7 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
{ {
WindowPrompt(tr("The game is on SD Card."), fmt(tr("To run GameCube games with %s you need to place them on an USB FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("The game is on SD Card."), fmt(tr("To run GameCube games with %s you need to place them on an USB FAT32 partition."),LoaderName), tr("OK"));
// Todo: Add here copySD2USB. // Todo: Add here copySD2USB.
return 0; return -1;
} }
// Check if the partition is the first primary partition on the drive // Check if the partition is the first primary partition on the drive
@ -483,20 +487,20 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
if(!found) if(!found)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary partition of the Hard Drive."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary partition of the Hard Drive."),LoaderName), tr("OK"));
return 0; return -1;
} }
// Check HDD sector size. Only 512 bytes/sector is supported by DIOS MIOS // Check HDD sector size. Only 512 bytes/sector is supported by DIOS MIOS
if(hdd_sector_size[usbport] != BYTES_PER_SECTOR) if(hdd_sector_size[usbport] != BYTES_PER_SECTOR)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to use a 512 bytes/sector Hard Drive."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to use a 512 bytes/sector Hard Drive."),LoaderName), tr("OK"));
return 0; return -1;
} }
if(usbHandle->GetPartitionClusterSize(usbHandle->GetLBAStart(USBport_partNum)) > 32768) if(usbHandle->GetPartitionClusterSize(usbHandle->GetLBAStart(USBport_partNum)) > 32768)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to use a partition with 32k bytes/cluster or less."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to use a partition with 32k bytes/cluster or less."),LoaderName), tr("OK"));
return 0; return -1;
} }
} }
@ -506,7 +510,7 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
if(((gameHdr->type == TYPE_GAME_GC_IMG) || (gameHdr->type == TYPE_GAME_GC_EXTRACTED)) && strncmp(RealPath, "usb", 3) == 0) if(((gameHdr->type == TYPE_GAME_GC_IMG) || (gameHdr->type == TYPE_GAME_GC_EXTRACTED)) && strncmp(RealPath, "usb", 3) == 0)
{ {
if(!GCGames::Instance()->CopyUSB2SD(gameHdr)) if(!GCGames::Instance()->CopyUSB2SD(gameHdr))
return 0; return -1;
RealPath = GCGames::Instance()->GetPath((const char *) gameHdr->id); RealPath = GCGames::Instance()->GetPath((const char *) gameHdr->id);
} }
@ -519,7 +523,7 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
if(IosLoader::GetDMLVersion() < DML_VERSION_DML_1_2) if(IosLoader::GetDMLVersion() < DML_VERSION_DML_1_2)
{ {
WindowPrompt(tr("Error:"), tr("You need to install DIOS MIOS Lite v1.2 or a newer version."), tr("OK")); WindowPrompt(tr("Error:"), tr("You need to install DIOS MIOS Lite v1.2 or a newer version."), tr("OK"));
return 0; return -1;
} }
if(dmlWidescreenChoice && IosLoader::GetDMLVersion() < DML_VERSION_DM_2_1) // DML Force Widescreen setting : added in DM v2.1+, config v1. if(dmlWidescreenChoice && IosLoader::GetDMLVersion() < DML_VERSION_DM_2_1) // DML Force Widescreen setting : added in DM v2.1+, config v1.
{ {
@ -566,7 +570,7 @@ int GameBooter::BootDIOSMIOS(struct discHdr *gameHdr)
{ {
int choice = WindowPrompt(gameHdr->title, tr("This game has multiple discs. Please select the disc to launch."), tr("Disc 1"), tr("Disc 2"), tr("Cancel")); int choice = WindowPrompt(gameHdr->title, tr("This game has multiple discs. Please select the disc to launch."), tr("Disc 1"), tr("Disc 2"), tr("Cancel"));
if(choice == 0) if(choice == 0)
return 0; return -1;
else if(choice == 2) else if(choice == 2)
bootDisc2 = true; bootDisc2 = true;
} }
@ -721,25 +725,25 @@ int GameBooter::BootDevolution(struct discHdr *gameHdr)
if(gameHdr->type == TYPE_GAME_GC_DISC) if(gameHdr->type == TYPE_GAME_GC_DISC)
{ {
WindowPrompt(tr("Error:"), tr("To run GameCube games from Disc you need to set the GameCube mode to MIOS in the game settings."), tr("OK")); WindowPrompt(tr("Error:"), tr("To run GameCube games from Disc you need to set the GameCube mode to MIOS in the game settings."), tr("OK"));
return 0; return -1;
} }
if(gameHdr->type == TYPE_GAME_GC_EXTRACTED) if(gameHdr->type == TYPE_GAME_GC_EXTRACTED)
{ {
WindowPrompt(tr("Error:"), fmt(tr("%s only accepts GameCube backups in ISO format."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("%s only accepts GameCube backups in ISO format."),LoaderName), tr("OK"));
return 0; return -1;
} }
if(!CheckAHBPROT()) if(!CheckAHBPROT())
{ {
WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK"));
return 0; return -1;
} }
if(strncmp(DeviceHandler::PathToFSName(RealPath), "FAT", 3) != 0) if(strncmp(DeviceHandler::PathToFSName(RealPath), "FAT", 3) != 0)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK"));
return 0; return -1;
} }
// Check if Devolution is available // Check if Devolution is available
@ -758,7 +762,7 @@ int GameBooter::BootDevolution(struct discHdr *gameHdr)
{ {
fclose(f); fclose(f);
WindowPrompt(tr("Error:"), tr("Devolution's loader.bin file can't be loaded."), tr("OK")); WindowPrompt(tr("Error:"), tr("Devolution's loader.bin file can't be loaded."), tr("OK"));
return 0; return -1;
} }
fread(loader_bin, 1, size, f); fread(loader_bin, 1, size, f);
@ -776,7 +780,7 @@ int GameBooter::BootDevolution(struct discHdr *gameHdr)
else else
{ {
WindowPrompt(tr("Error:"), tr("To run GameCube games with Devolution you need the loader.bin file in your Devolution Loader Path."), tr("OK")); WindowPrompt(tr("Error:"), tr("To run GameCube games with Devolution you need the loader.bin file in your Devolution Loader Path."), tr("OK"));
return 0; return -1;
} }
@ -897,7 +901,7 @@ int GameBooter::BootDevolution(struct discHdr *gameHdr)
if(!iso_file) if(!iso_file)
{ {
WindowPrompt(tr("Error:"), tr("File not found."), tr("OK")); WindowPrompt(tr("Error:"), tr("File not found."), tr("OK"));
return 0; return -1;
} }
u8 *lowmem = (u8*)0x80000000; u8 *lowmem = (u8*)0x80000000;
fread(lowmem, 1, 32, iso_file); fread(lowmem, 1, 32, iso_file);
@ -966,7 +970,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(!CheckAHBPROT()) if(!CheckAHBPROT())
{ {
WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK"));
return 0; return -1;
} }
@ -977,7 +981,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(strncmp(DeviceHandler::PathToFSName(Settings.GameCubePath), "FAT", 3) != 0) if(strncmp(DeviceHandler::PathToFSName(Settings.GameCubePath), "FAT", 3) != 0)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' to an USB FAT32 partition."),LoaderName), tr("OK"));
return 0; return -1;
} }
// Check if the partition is a primary // Check if the partition is a primary
@ -987,7 +991,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(usbHandle->GetPartitionTableType(USBport_partNum) != MBR) if(usbHandle->GetPartitionTableType(USBport_partNum) != MBR)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary FAT32 partition."),LoaderName), tr("OK"));
return 0; return -1;
} }
// check if the partition is the first FAT32 of the drive // check if the partition is the first FAT32 of the drive
@ -1006,7 +1010,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(!found) if(!found)
{ {
WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary FAT32 partition."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("To run GameCube games with %s you need to set your 'Main GameCube Path' on the first primary FAT32 partition."),LoaderName), tr("OK"));
return 0; return -1;
} }
} }
@ -1029,7 +1033,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
// Nintendont boot.dol not found // Nintendont boot.dol not found
WindowPrompt(tr("Error:"), tr("To run GameCube games with Nintendont you need the boot.dol file in your Nintendont Loader Path."), tr("OK")); WindowPrompt(tr("Error:"), tr("To run GameCube games with Nintendont you need the boot.dol file in your Nintendont Loader Path."), tr("OK"));
return 0; return -1;
} }
gprintf("NIN: Loader path = %s \n",NIN_loader_path); gprintf("NIN: Loader path = %s \n",NIN_loader_path);
gprintf("NIN: Game path = %s \n",RealPath); gprintf("NIN: Game path = %s \n",RealPath);
@ -1061,7 +1065,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(NINLoaderTime == mktime(&time)) if(NINLoaderTime == mktime(&time))
{ {
WindowPrompt(tr("Error:"), tr("USBloaderGX r1218 is required for Nintendont Alpha v0.1. Please update your Nintendont boot.dol version."), tr("Ok")); WindowPrompt(tr("Error:"), tr("USBloaderGX r1218 is required for Nintendont Alpha v0.1. Please update your Nintendont boot.dol version."), tr("Ok"));
return 0; return -1;
} }
// r01 - r40 // r01 - r40
@ -1075,7 +1079,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(NINLoaderTime < mktime(&time) && strncmp(RealPath, "usb", 3) == 0) if(NINLoaderTime < mktime(&time) && strncmp(RealPath, "usb", 3) == 0)
{ {
if(WindowPrompt(tr("Warning:"), tr("This Nintendont version does not support games on USB."), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), tr("This Nintendont version does not support games on USB."), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
@ -1105,7 +1109,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(gameHdr->type == TYPE_GAME_GC_DISC && NINLoaderTime < mktime(&time)) if(gameHdr->type == TYPE_GAME_GC_DISC && NINLoaderTime < mktime(&time))
{ {
WindowPrompt(tr("Error:"), tr("To run GameCube games from Disc you need to set the GameCube mode to MIOS in the game settings."), tr("OK")); WindowPrompt(tr("Error:"), tr("To run GameCube games from Disc you need to set the GameCube mode to MIOS in the game settings."), tr("OK"));
return 0; return -1;
} }
// v3.304 - Controller.ini is now optional // v3.304 - Controller.ini is now optional
@ -1140,7 +1144,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
int choice = WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't verify Nintendont boot.dol file. Launch this boot.dol anyway?"), tr("Yes"), tr("Cancel")); int choice = WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't verify Nintendont boot.dol file. Launch this boot.dol anyway?"), tr("Yes"), tr("Cancel"));
if(choice == 0) if(choice == 0)
return 0; return -1;
} }
} }
@ -1182,7 +1186,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
} }
// Check kenobiwii.bin // Check kenobiwii.bin
if(ocarinaChoice || (ninDebugChoice && !isWiiU())) if(NINRev < 336 && (ocarinaChoice || (ninDebugChoice && !isWiiU())))
{ {
char kenobiwii_path[30]; char kenobiwii_path[30];
snprintf(kenobiwii_path, sizeof(kenobiwii_path), "%s:/sneek/kenobiwii.bin", DeviceHandler::GetDevicePrefix(RealPath)); snprintf(kenobiwii_path, sizeof(kenobiwii_path), "%s:/sneek/kenobiwii.bin", DeviceHandler::GetDevicePrefix(RealPath));
@ -1202,21 +1206,21 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
gprintf("NIN: Couldn't copy %s to %s.\n", kenobiwii_srcpath, kenobiwii_path); gprintf("NIN: Couldn't copy %s to %s.\n", kenobiwii_srcpath, kenobiwii_path);
RemoveFile(kenobiwii_path); RemoveFile(kenobiwii_path);
if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
else else
{ {
gprintf("kenobiwii source path = %s Not found.\n", kenobiwii_srcpath); gprintf("kenobiwii source path = %s Not found.\n", kenobiwii_srcpath);
if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
else else
{ {
gprintf("kenobiwii path = %s Not found.\n", kenobiwii_path); gprintf("kenobiwii path = %s Not found.\n", kenobiwii_path);
if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), fmt(tr("To use ocarina with %s you need the %s file."), LoaderName, kenobiwii_path), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
} }
@ -1242,7 +1246,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
if(NINRev < 304) // HID is always enabled and controller.ini optional since r304 if(NINRev < 304) // HID is always enabled and controller.ini optional since r304
{ {
if(WindowPrompt(tr("Warning:"), fmt(tr("To use HID with %s you need the %s file."), LoaderName, controllerini_path), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), fmt(tr("To use HID with %s you need the %s file."), LoaderName, controllerini_path), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
} }
@ -1269,7 +1273,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
snprintf(controllerini_path, sizeof(controllerini_path), "%s:/controller.ini", DeviceHandler::GetDevicePrefix(RealPath)); snprintf(controllerini_path, sizeof(controllerini_path), "%s:/controller.ini", DeviceHandler::GetDevicePrefix(RealPath));
if(WindowPrompt(tr("Warning:"), fmt(tr("To use HID with %s you need the %s file."), LoaderName, controllerini_path), tr("Continue"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), fmt(tr("To use HID with %s you need the %s file."), LoaderName, controllerini_path), tr("Continue"), tr("Cancel")) == 0)
return 0; return -1;
} }
} }
@ -1290,7 +1294,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
int choice = WindowPrompt(gameHdr->title, tr("This game has multiple discs. Please select the disc to launch."), tr("Disc 1"), tr("Disc 2"), tr("Cancel")); int choice = WindowPrompt(gameHdr->title, tr("This game has multiple discs. Please select the disc to launch."), tr("Disc 1"), tr("Disc 2"), tr("Cancel"));
if(choice == 0) if(choice == 0)
return 0; return -1;
else if(choice == 2) else if(choice == 2)
bootDisc2 = true; bootDisc2 = true;
} }
@ -1321,7 +1325,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
gprintf("Not enough memory to create nincfg.bin file.\n"); gprintf("Not enough memory to create nincfg.bin file.\n");
WindowPrompt(tr("Error:"), tr("Could not write file."), tr("OK")); WindowPrompt(tr("Error:"), tr("Could not write file."), tr("OK"));
return 0; return -1;
} }
memset(nin_config, 0, sizeof(NIN_CFG)); memset(nin_config, 0, sizeof(NIN_CFG));
@ -1481,7 +1485,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
gprintf("Could not open NINCfgPath in write mode"); gprintf("Could not open NINCfgPath in write mode");
int choice = WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't write Nintendont config file. Launch Nintendont anyway?"), tr("Yes"), tr("Cancel")); int choice = WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't write Nintendont config file. Launch Nintendont anyway?"), tr("Yes"), tr("Cancel"));
if(choice == 0) if(choice == 0)
return 0; return -1;
} }
// Copy Nintendont Config file to game path // Copy Nintendont Config file to game path
@ -1495,7 +1499,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
gprintf("\nError: Couldn't copy %s to %s.\n", NINCfgPath, NINDestPath); gprintf("\nError: Couldn't copy %s to %s.\n", NINCfgPath, NINDestPath);
RemoveFile(NINDestPath); RemoveFile(NINDestPath);
if(WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't write Nintendont config file. Launch Nintendont anyway?"), tr("Yes"), tr("Cancel")) == 0) if(WindowPrompt(tr("Warning:"), tr("USBloaderGX couldn't write Nintendont config file. Launch Nintendont anyway?"), tr("Yes"), tr("Cancel")) == 0)
return 0; return -1;
} }
gprintf("done\n"); gprintf("done\n");
} }
@ -1509,7 +1513,7 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
LoadFileToMem(NIN_loader_path, &buffer, &filesize); LoadFileToMem(NIN_loader_path, &buffer, &filesize);
if(!buffer) if(!buffer)
{ {
return 0; return -1;
} }
FreeHomebrewBuffer(); FreeHomebrewBuffer();
CopyHomebrewMemory(buffer, 0, filesize); CopyHomebrewMemory(buffer, 0, filesize);

View File

@ -71,29 +71,29 @@ static void CreateNandPath(const char *path)
CreateSubfolder(path); CreateSubfolder(path);
} }
void CreateSavePath(const struct discHdr *hdr) void CreateSavePath(const struct discHdr *hdr, const char *NandEmuPath)
{ {
char nandPath[512]; char nandPath[512];
snprintf(nandPath, sizeof(nandPath), "%s/import", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/import", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/meta", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/meta", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/shared1", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/shared1", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/shared2", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/shared2", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/sys", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/sys", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/ticket", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/ticket", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/tmp", Settings.NandEmuPath); snprintf(nandPath, sizeof(nandPath), "%s/tmp", NandEmuPath);
CreateNandPath(nandPath); CreateNandPath(nandPath);
const char *titlePath = "title/00010000"; const char *titlePath = "title/00010000";
@ -107,10 +107,10 @@ void CreateSavePath(const struct discHdr *hdr)
if(hdr->type == TYPE_GAME_NANDCHAN || hdr->type == TYPE_GAME_EMUNANDCHAN) if(hdr->type == TYPE_GAME_NANDCHAN || hdr->type == TYPE_GAME_EMUNANDCHAN)
titlePath = "title/00010001"; titlePath = "title/00010001";
snprintf(nandPath, sizeof(nandPath), "%s/%s/%02x%02x%02x%02x/data", Settings.NandEmuPath, titlePath, hdr->id[0], hdr->id[1], hdr->id[2], hdr->id[3]); snprintf(nandPath, sizeof(nandPath), "%s/%s/%02x%02x%02x%02x/data", NandEmuPath, titlePath, hdr->id[0], hdr->id[1], hdr->id[2], hdr->id[3]);
CreateNandPath(nandPath); CreateNandPath(nandPath);
snprintf(nandPath, sizeof(nandPath), "%s/%s/%02x%02x%02x%02x/content", Settings.NandEmuPath, titlePath, hdr->id[0], hdr->id[1], hdr->id[2], hdr->id[3]); snprintf(nandPath, sizeof(nandPath), "%s/%s/%02x%02x%02x%02x/content", NandEmuPath, titlePath, hdr->id[0], hdr->id[1], hdr->id[2], hdr->id[3]);
CreateNandPath(nandPath); CreateNandPath(nandPath);
strcat(nandPath, "/title.tmd"); strcat(nandPath, "/title.tmd");

View File

@ -4,6 +4,6 @@
#include "usbloader/disc.h" #include "usbloader/disc.h"
void CreateTitleTMD(const char *path, const struct discHdr *hdr); void CreateTitleTMD(const char *path, const struct discHdr *hdr);
void CreateSavePath(const struct discHdr *hdr); void CreateSavePath(const struct discHdr *hdr, const char *NandEmuPath);
#endif #endif