mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-09-09 09:03:20 +02:00
![Cyan](/assets/img/avatar_default.png)
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.
310 lines
9.1 KiB
C++
310 lines
9.1 KiB
C++
#include <unistd.h>
|
|
#include "menus.h"
|
|
#include "GameCube/GCGames.h"
|
|
#include "GameCube/GCDumper.hpp"
|
|
#include "usbloader/usbstorage2.h"
|
|
#include "usbloader/wbfs.h"
|
|
#include "usbloader/disc.h"
|
|
#include "usbloader/GameList.h"
|
|
#include "prompts/ProgressWindow.h"
|
|
#include "prompts/GCMultiDiscMenu.h"
|
|
#include "themes/CTheme.h"
|
|
#include "utils/tools.h"
|
|
#include "system/IosLoader.h"
|
|
|
|
#define WII_MAGIC 0x5D1C9EA3
|
|
|
|
extern int install_abort_signal;
|
|
float gamesize = 0.0f;
|
|
|
|
/****************************************************************************
|
|
* MenuGCInstall
|
|
***************************************************************************/
|
|
int MenuGCInstall()
|
|
{
|
|
GCDumper gcDumper;
|
|
if(gcDumper.ReadDiscHeader() < 0)
|
|
{
|
|
WindowPrompt(tr("Error"), tr("Error reading disc"), tr("OK"));
|
|
return MENU_DISCLIST;
|
|
}
|
|
|
|
std::vector<u32> installGames;
|
|
|
|
if(gcDumper.GetDiscHeaders().size() == 0)
|
|
{
|
|
WindowPrompt(tr("Error"), tr("No games found on the disc"), tr("OK"));
|
|
return MENU_DISCLIST;
|
|
}
|
|
else if(gcDumper.GetDiscHeaders().size() > 1)
|
|
{
|
|
//! Multi game disc, lets ask the user which games to install
|
|
GCMultiDiscMenu gcMenu(gcDumper.GetDiscHeaders());
|
|
gcMenu.SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
|
|
gcMenu.SetEffect(EFFECT_FADE, 20);
|
|
mainWindow->SetState(STATE_DISABLED);
|
|
mainWindow->Append(&gcMenu);
|
|
|
|
int choice = gcMenu.ShowSelection();
|
|
|
|
gcMenu.SetEffect(EFFECT_FADE, -20);
|
|
while(gcMenu.GetEffect() > 0) usleep(1000);
|
|
|
|
mainWindow->Remove(&gcMenu);
|
|
mainWindow->SetState(STATE_DEFAULT);
|
|
|
|
installGames = gcMenu.GetSelectedGames();
|
|
|
|
if(choice == 0 || installGames.size() == 0)
|
|
return MENU_DISCLIST;
|
|
}
|
|
else
|
|
{
|
|
if(!WindowPrompt(tr( "Continue to install game?" ), gcDumper.GetDiscHeaders().at(0).title, tr("Yes"), tr( "Cancel" )))
|
|
return MENU_DISCLIST;
|
|
|
|
installGames.push_back(0);
|
|
}
|
|
|
|
//! setup dumper settings
|
|
gcDumper.SetCompressed(Settings.GCInstallCompressed);
|
|
gcDumper.SetCompressed(Settings.GCInstallAligned);
|
|
|
|
//! If a different main path than the SD path is selected ask where to install
|
|
int destination = 1;
|
|
if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0)
|
|
destination = WindowPrompt(tr("Where should the game be installed to?"), 0, tr("Main Path"), tr("SD Path"), tr("Cancel"));
|
|
if(!destination)
|
|
return MENU_DISCLIST;
|
|
|
|
//! Alert the user if he is dumping on SD with DIOS MIOS (USB) installed
|
|
if(destination == 2 && IosLoader::GetMIOSInfo() == DIOS_MIOS)
|
|
{
|
|
if(!WindowPrompt(tr("Are you sure you want to install on SD?"), ("You have DIOS-MIOS installed so the game need to be on a FAT32 USB. You will need to install DIOS-MIOS Lite to run this game from SD."), tr("Yes"), tr( "Cancel" )))
|
|
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
|
|
wiilight(1);
|
|
|
|
int result = 0;
|
|
int installed_games = 0;
|
|
|
|
for(u32 i = 0; i < installGames.size(); ++i)
|
|
{
|
|
//! check if the game is already installed on SD/USB
|
|
if(GCGames::Instance()->IsInstalled((char *)gcDumper.GetDiscHeaders().at(installGames[i]).id, gcDumper.GetDiscHeaders().at(installGames[i]).disc_no))
|
|
{
|
|
WindowPrompt(tr("Game is already installed:"), gcDumper.GetDiscHeaders().at(installGames[i]).title, tr("OK"));
|
|
if(i+1 < installGames.size()) {
|
|
continue;
|
|
}
|
|
else if(i == 0)
|
|
{
|
|
result = MENU_DISCLIST;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check Disc2 installation format (DML 2.6+ auto-swap feature doesn't work with extracted game format)
|
|
if(Settings.GCInstallCompressed && gcDumper.GetDiscHeaders().at(installGames[i]).disc_no == 1)
|
|
{
|
|
int choice = WindowPrompt(tr(gcDumper.GetDiscHeaders().at(installGames[i]).title), tr("Disc2 needs to be installed in uncompressed format to work with DM(L) v2.6+, are you sure you want to install in compressed format?"), tr("Yes"), tr("Cancel"));
|
|
if(choice == 0)
|
|
{
|
|
if(i+1 < installGames.size()) {
|
|
continue;
|
|
}
|
|
else if(i == 0)
|
|
{
|
|
result = MENU_DISCLIST;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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], installedGamePath);
|
|
if(ret >= 0) {
|
|
//! success
|
|
installed_games++;
|
|
}
|
|
else if(ret == PROGRESS_CANCELED)
|
|
{
|
|
result = MENU_DISCLIST;
|
|
break;
|
|
}
|
|
else if(ret < 0)
|
|
{
|
|
//! Error occured, ask the user what to do if there are more games to install
|
|
if(i+1 < installGames.size())
|
|
{
|
|
if(!WindowPrompt(tr( "Install Error!" ), tr("Do you want to continue with next game?"), tr("Yes"), tr( "Cancel" )))
|
|
{
|
|
result = MENU_DISCLIST;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WindowPrompt(tr( "Install Error!" ), 0, tr( "Back" ));
|
|
result = MENU_DISCLIST;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
wiilight(0);
|
|
Settings.GameCubeSource = oldGameCubeSource;
|
|
GCGames::Instance()->LoadAllGames();
|
|
|
|
//! no game was installed so don't show successfully installed prompt
|
|
if(installed_games == 0)
|
|
return result;
|
|
|
|
gameList.FilterList();
|
|
bgMusic->Pause();
|
|
GuiSound instsuccess(Resources::GetFile("success.ogg"), Resources::GetFileSize("success.ogg"), Settings.sfxvolume);
|
|
instsuccess.SetVolume(Settings.sfxvolume);
|
|
instsuccess.SetLoop(0);
|
|
instsuccess.Play();
|
|
char gamesTxt[20];
|
|
snprintf(gamesTxt, sizeof(gamesTxt), "%i %s", installed_games, tr("Games"));
|
|
WindowPrompt(tr("Successfully installed:"), installGames.size() > 1 ? gamesTxt : gcDumper.GetDiscHeaders().at(installGames[0]).title, tr( "OK" ));
|
|
instsuccess.Stop();
|
|
bgMusic->Resume();
|
|
|
|
return MENU_DISCLIST;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* MenuInstall
|
|
***************************************************************************/
|
|
int MenuInstall()
|
|
{
|
|
gprintf("\nMenuInstall()\n");
|
|
|
|
static struct discHdr headerdisc ATTRIBUTE_ALIGN( 32 );
|
|
|
|
Disc_SetUSB(NULL);
|
|
|
|
int ret, choice = 0;
|
|
|
|
ret = DiscWait(tr( "Insert Disk" ), tr( "Waiting..." ), tr( "Cancel" ), 0, 0);
|
|
if (ret < 0)
|
|
{
|
|
WindowPrompt(tr( "Error reading Disc" ), 0, tr( "Back" ));
|
|
return MENU_DISCLIST;
|
|
}
|
|
ret = Disc_Open();
|
|
if (ret < 0)
|
|
{
|
|
WindowPrompt(tr( "Could not open Disc" ), 0, tr( "Back" ));
|
|
return MENU_DISCLIST;
|
|
}
|
|
|
|
memset(&headerdisc, 0, sizeof(struct discHdr));
|
|
|
|
Disc_ReadHeader(&headerdisc);
|
|
|
|
if ((headerdisc.magic != WII_MAGIC) && (headerdisc.gc_magic != GCGames::MAGIC))
|
|
{
|
|
choice = WindowPrompt(tr( "Not a Wii or a Game Cube Disc" ), tr( "Insert a Wii or a Game Cube Disc!" ), tr( "OK" ), tr( "Back" ));
|
|
if (choice == 1)
|
|
return MenuInstall();
|
|
else
|
|
return MENU_DISCLIST;
|
|
}
|
|
|
|
if(headerdisc.gc_magic == GCGames::MAGIC)
|
|
{
|
|
return MenuGCInstall();
|
|
}
|
|
|
|
ret = WBFS_CheckGame(headerdisc.id);
|
|
if (ret)
|
|
{
|
|
WindowPrompt(tr( "Game is already installed:" ), headerdisc.title, tr( "Back" ));
|
|
return MENU_DISCLIST;
|
|
}
|
|
|
|
f32 freespace, used;
|
|
|
|
WBFS_DiskSpace(&used, &freespace);
|
|
gamesize = (float) WBFS_EstimeGameSize();
|
|
|
|
char gametxt[strlen(headerdisc.title) + 16];
|
|
snprintf(gametxt, sizeof(gametxt), "%s : %.2fGB", headerdisc.title, gamesize/GB_SIZE);
|
|
|
|
wiilight(1);
|
|
choice = WindowPrompt(tr( "Continue to install game?" ), gametxt, tr( "OK" ), tr( "Cancel" ));
|
|
|
|
if (choice == 1)
|
|
{
|
|
sprintf(gametxt, "%s", tr( "Installing game:" ));
|
|
|
|
if (gamesize/GB_SIZE > freespace)
|
|
{
|
|
char errortxt[50];
|
|
sprintf(errortxt, "%s: %.2fGB, %s: %.2fGB", tr( "Game Size" ), gamesize/GB_SIZE, tr( "Free Space" ), freespace);
|
|
WindowPrompt(tr( "Not enough free space!" ), errortxt, tr( "OK" ));
|
|
}
|
|
else
|
|
{
|
|
StartProgress(gametxt, headerdisc.title, 0, true, true);
|
|
ProgressCancelEnable(true);
|
|
ret = WBFS_AddGame();
|
|
ProgressCancelEnable(false);
|
|
ProgressStop();
|
|
wiilight(0);
|
|
if (install_abort_signal)
|
|
{
|
|
WindowPrompt(tr( "Install Canceled" ), 0, tr( "OK" ));
|
|
}
|
|
else if (ret != 0)
|
|
{
|
|
WindowPrompt(tr( "Install Error!" ), 0, tr( "Back" ));
|
|
}
|
|
else
|
|
{
|
|
ShowProgress(tr("Install finished"), headerdisc.title, tr("Reloading game list now, please wait..."), gamesize, gamesize, true, true);
|
|
gameList.ReadGameList(); //get the entries again
|
|
gameList.FilterList();
|
|
bgMusic->Pause();
|
|
GuiSound instsuccess(Resources::GetFile("success.ogg"), Resources::GetFileSize("success.ogg"), Settings.sfxvolume);
|
|
instsuccess.SetVolume(Settings.sfxvolume);
|
|
instsuccess.SetLoop(0);
|
|
instsuccess.Play();
|
|
WindowPrompt(tr( "Successfully installed:" ), headerdisc.title, tr( "OK" ));
|
|
instsuccess.Stop();
|
|
bgMusic->Resume();
|
|
}
|
|
}
|
|
}
|
|
|
|
//Turn off the WiiLight
|
|
wiilight(0);
|
|
gamesize = 0.0f;
|
|
|
|
return MENU_DISCLIST;
|
|
}
|