* Fixed installation destination for multi-Disc based games.

Second ISO is now properly going into the existing folder instead
  of using the Disc's internal Game Title.
* Prevent deleting a folder when installation is canceled if
  the folder still contains another disc number.
* Added a new setting to select GameCube game source: SD, USB, Auto
  Auto = based on DIOS MIOS (Lite).
  This new setting fix two known problems:
  - Device selection for Devolution is no more dependent of
    the installed DM(L) type. (Select manually before launching a game)
  - Installation of a game on a device if the game is already
    on another device is now possible.
This commit is contained in:
Cyan 2012-12-09 21:36:32 +00:00
parent 77f7daf9dc
commit 9e993326e5
10 changed files with 106 additions and 28 deletions

View File

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

View File

@ -201,7 +201,7 @@ int GCDumper::ReadDiscInfo(const u64 &game_offset)
return 0;
}
s32 GCDumper::InstallGame(const char *installpath, u32 game)
s32 GCDumper::InstallGame(const char *installpath, u32 game, const char *installedGamePath)
{
if(!ReadBuffer || game >= discHeaders.size() || game >= gameOffsets.size() || game >= gameSizes.size())
return -1;
@ -266,6 +266,10 @@ s32 GCDumper::InstallGame(const char *installpath, u32 game)
// snprintf(gamepath, sizeof(gamepath), "%s%s [%.6s]%s/", installpath, gametitle, gcheader.id, Disc ? "2" : ""); // Disc2 currently needs to be on the same folder.
snprintf(gamepath, sizeof(gamepath), "%s%s [%.6s]/", installpath, gametitle, gcheader.id);
// If another Disc from the same gameID already exists, let's use that path
if(strlen((char *)installedGamePath) != 0)
snprintf(gamepath, sizeof(gamepath), "%s/", installedGamePath);
CreateSubfolder(gamepath);
// snprintf(gamepath, sizeof(gamepath), "%s%s [%.6s]%s/game.iso", installpath, gametitle, gcheader.id, Disc ? "2" : ""); // Disc2 currently needs to be on the same folder.
@ -384,9 +388,12 @@ s32 GCDumper::InstallGame(const char *installpath, u32 game)
if(result < 0)
{
RemoveFile(gamepath);
char *pathPtr = strrchr(gamepath, '/');
if(pathPtr) *pathPtr = 0;
RemoveFile(gamepath);
if(strlen((char *)installedGamePath) == 0) // If no other disc is installed in that folder, delete it.
{
char *pathPtr = strrchr(gamepath, '/');
if(pathPtr) *pathPtr = 0;
RemoveFile(gamepath);
}
if(result != PROGRESS_CANCELED)
ShowError(tr("Disc read error."));

View File

@ -37,7 +37,7 @@ class GCDumper
public:
GCDumper();
~GCDumper();
s32 InstallGame(const char *installpath, u32 game);
s32 InstallGame(const char *installpath, u32 game, const char *installedGamePath);
s32 ReadDiscHeader(void);
int ReadDiscInfo(const u64 &game_offset);
void SetForceAlign(bool b) { force_align32 = b; }

View File

@ -222,38 +222,47 @@ u32 GCGames::LoadAllGames(void)
sdGCList.clear();
sdGCPathList.clear();
LoadGameList(Settings.GameCubePath, HeaderList, PathList);
if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) == 0 || Settings.GameCubeSource != GC_SOURCE_SD)
LoadGameList(Settings.GameCubePath, HeaderList, PathList);
if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0)
if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0 && (Settings.GameCubeSource != GC_SOURCE_MAIN))
{
LoadGameList(Settings.GameCubeSDPath, sdGCList, sdGCPathList);
for(u32 i = 0; i < sdGCList.size(); ++i)
{
u32 n;
for(n = 0; n < HeaderList.size(); ++n)
if(Settings.GameCubeSource == GC_SOURCE_AUTO)
{
//! Display only one game if it is present on both SD and USB.
if(memcmp(HeaderList[n].id, sdGCList[i].id, 6) == 0)
u32 n;
for(n = 0; n < HeaderList.size(); ++n)
{
if(IosLoader::GetMIOSInfo() == DIOS_MIOS) // DIOS MIOS - Show only the game on USB
//! Display only one game if it is present on both SD and USB.
if(memcmp(HeaderList[n].id, sdGCList[i].id, 6) == 0)
{
break;
}
else // replace the one loaded from USB with the same games on SD since we can load them directly
{
memcpy(&HeaderList[n], &sdGCList[i], sizeof(struct discHdr));
PathList[n] = sdGCPathList[i];
break;
if(IosLoader::GetMIOSInfo() == DIOS_MIOS) // DIOS MIOS - Show only the game on USB
{
break;
}
else // replace the one loaded from USB with the same games on SD since we can load them directly
{
memcpy(&HeaderList[n], &sdGCList[i], sizeof(struct discHdr));
PathList[n] = sdGCPathList[i];
break;
}
}
}
}
// Not available in the main GC path
if(n == HeaderList.size()) {
HeaderList.push_back(sdGCList[i]);
PathList.push_back(sdGCPathList[i]);
// Not available in the main GC path
if(n == HeaderList.size()) {
HeaderList.push_back(sdGCList[i]);
PathList.push_back(sdGCPathList[i]);
}
}
else // GC_SOURCE_SD, or GC_SOURCE_BOTH (show duplicates)
{
HeaderList.push_back(sdGCList[i]);
PathList.push_back(sdGCPathList[i]);
}
}
}
@ -386,7 +395,7 @@ bool GCGames::IsInstalled(const char *gameID, u8 disc_number) const
{
if(memcmp(HeaderList[n].id, gameID, 6) == 0)
{
if(HeaderList[n].type == TYPE_GAME_GC_EXTRACTED)
if(HeaderList[n].type == TYPE_GAME_GC_EXTRACTED || Settings.GCInstallCompressed)
return true; // Multi-disc games in extracted form are currently unsupported by DML, no need to check further.
if(HeaderList[n].disc_no == disc_number) // Disc number already in headerList. If Disc2 is loaded in headerList, then Disc1 is not installed yet

View File

@ -84,6 +84,11 @@ int MenuGCInstall()
return MENU_DISCLIST;
}
// Load only available games from the selected device
int oldGameCubeSource = Settings.GameCubeSource;
Settings.GameCubeSource = destination-1;
GCGames::Instance()->LoadAllGames();
const char *InstallPath = destination == 1 ? Settings.GameCubePath : Settings.GameCubeSDPath;
//! Start of install process, enable wii slot light
@ -125,8 +130,20 @@ int MenuGCInstall()
}
}
// Check if another Disc number from the same game is already installed on this device
GCGames::Instance()->LoadAllGames(); // refresh installed game list
char installedGamePath[512];
if(GCGames::Instance()->IsInstalled((char *)gcDumper.GetDiscHeaders().at(installGames[i]).id, gcDumper.GetDiscHeaders().at(installGames[i]).disc_no == 0 ? 1 : 0))
{
snprintf(installedGamePath, sizeof(installedGamePath), GCGames::Instance()->GetPath((char *)gcDumper.GetDiscHeaders().at(installGames[i]).id));
char *pathPtr = strrchr(installedGamePath, '/');
if(pathPtr) *pathPtr = 0;
}
else
installedGamePath[0] = 0;
// game is not yet installed so let's install it
int ret = gcDumper.InstallGame(InstallPath, installGames[i]);
int ret = gcDumper.InstallGame(InstallPath, installGames[i], installedGamePath);
if(ret >= 0) {
//! success
installed_games++;
@ -157,6 +174,7 @@ int MenuGCInstall()
}
wiilight(0);
Settings.GameCubeSource = oldGameCubeSource;
GCGames::Instance()->LoadAllGames();
//! no game was installed so don't show successfully installed prompt

View File

@ -169,6 +169,7 @@ void CSettings::SetDefault()
BannerProjectionHeight = (Settings.PAL50 ? 448.0f : (NTSC ? 470.0f : 464.0f));
GCBannerScale = 1.5f;
GameCubeMode = GC_MODE_MIOS;
GameCubeSource = AUTO;
DMLVideo = DML_VIDEO_AUTO;
DMLProgPatch = OFF;
DMLNMM = OFF;
@ -398,6 +399,7 @@ bool CSettings::Save()
fprintf(file, "GameCubePath = %s\n", GameCubePath);
fprintf(file, "GameCubeSDPath = %s\n", GameCubeSDPath);
fprintf(file, "GameCubeMode = %d\n", GameCubeMode);
fprintf(file, "GameCubeSource = %d\n", GameCubeSource);
fprintf(file, "DMLVideo = %d\n", DMLVideo);
fprintf(file, "DMLProgPatch = %d\n", DMLProgPatch);
fprintf(file, "DMLNMM = %d\n", DMLNMM);
@ -806,6 +808,11 @@ bool CSettings::SetSetting(char *name, char *value)
GameCubeMode = atoi(value);
return true;
}
else if (strcmp(name, "GameCubeSource") == 0)
{
GameCubeSource = atoi(value);
return true;
}
else if (strcmp(name, "DMLVideo") == 0)
{
DMLVideo = atoi(value);

View File

@ -171,6 +171,7 @@ class CSettings
float BannerProjectionHeight;
float GCBannerScale;
short GameCubeMode;
short GameCubeSource;
short DMLVideo;
short DMLProgPatch;
short DMLNMM;

View File

@ -280,6 +280,16 @@ enum
};
enum
{
GC_SOURCE_MAIN,
GC_SOURCE_SD,
GC_SOURCE_AUTO,
// GC_SOURCE_BOTH, // GCGames::getPath(GameID) always returns the first encountered path in the gameList
CG_SOURCE_MAX_CHOICE
};
enum
{
DEVO_MC_OFF,

View File

@ -35,6 +35,7 @@
#include "usbloader/GameList.h"
#include "utils/tools.h"
#include "menu.h"
#include "gamecube/GCGames.h"
static const char * OnOffText[] =
{
@ -115,6 +116,14 @@ static const char * GCMode[] =
trNOOP( "Devolution" ),
};
static const char * GCSourceText[] =
{
trNOOP( "Main Path" ),
trNOOP( "SD Path" ),
trNOOP( "Auto" ),
trNOOP( "Both" ),
};
static const char * DMLVideoText[] =
{
trNOOP( "DML Auto" ),
@ -167,6 +176,7 @@ LoaderSettings::LoaderSettings()
Options->SetName(Idx++, "%s", tr( "Debugger Paused Start" ));
Options->SetName(Idx++, "%s", tr( "Channel Launcher" ));
Options->SetName(Idx++, "%s", tr( "GameCube Mode" ));
Options->SetName(Idx++, "%s", tr( "GameCube Source" ));
Options->SetName(Idx++, "%s", tr( "DML Video Mode" ));
Options->SetName(Idx++, "%s", tr( "DML Progressive Patch" ));
Options->SetName(Idx++, "%s", tr( "DML NMM Mode" ));
@ -184,6 +194,7 @@ LoaderSettings::LoaderSettings()
SetOptionValues();
oldLoaderMode = Settings.LoaderMode;
oldGameCubeSource = Settings.GameCubeSource;
}
LoaderSettings::~LoaderSettings()
@ -199,6 +210,11 @@ LoaderSettings::~LoaderSettings()
gameList.LoadUnfiltered();
GameTitles.LoadTitlesFromGameTDB(Settings.titlestxt_path, false);
}
if(oldGameCubeSource != Settings.GameCubeSource)
{
GCGames::Instance()->LoadAllGames();
}
}
void LoaderSettings::SetOptionValues()
@ -270,6 +286,9 @@ void LoaderSettings::SetOptionValues()
//! Settings: GameCube Mode
Options->SetValue(Idx++, "%s", tr(GCMode[Settings.GameCubeMode]));
//! Settings: GameCube Source
Options->SetValue(Idx++, "%s", tr(GCSourceText[Settings.GameCubeSource]));
//! Settings: DML Video Mode
Options->SetValue(Idx++, "%s", tr(DMLVideoText[Settings.DMLVideo]));
@ -458,6 +477,12 @@ int LoaderSettings::GetMenuInternal()
if (++Settings.GameCubeMode >= CG_MODE_MAX_CHOICE) Settings.GameCubeMode = 0;
}
//! Settings: GameCube Source
else if (ret == ++Idx)
{
if (++Settings.GameCubeSource >= CG_SOURCE_MAX_CHOICE) Settings.GameCubeSource = 0;
}
//! Settings: DML Video Mode
else if (ret == ++Idx)
{

View File

@ -36,6 +36,7 @@ class LoaderSettings : public SettingsMenu
int GetMenuInternal();
short oldLoaderMode;
short oldGameCubeSource;
OptionList GuiOptions;
};