mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-10-02 03:35:09 +02:00
77f7daf9dc
* Added auto-detection and loading multi-Disc games with both Devolution and DIOS MIOS (Lite). The Disc 2 must be named disc2.iso and placed in the same folder than game.iso * DML: Prevent temporary ocarina .gct file copy if the game is launched from disc Note: If you use "GameCube compress" option (Extracted game format): - If one of the disc is already extracted, it will not allows you to dump another disc (as it's now using the same folder, it would overwrite files from the other disc) - If Disc 1 doesn't exist, it will tell you that disc 2 needs to be in ISO format, but will asks if you really want to install the game in extracted format.
292 lines
8.3 KiB
C++
292 lines
8.3 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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// game is not yet installed so let's install it
|
|
int ret = gcDumper.InstallGame(InstallPath, installGames[i]);
|
|
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);
|
|
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;
|
|
}
|