mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-29 14:44:17 +01:00
4d6e0fe412
Add button to mount DVD drive. Not completely tested, but somewhat. *Tested and working* retail Wii DVD Wii backup Wii backup w/ alt dol (redsteel) Wii backup w/ alt dol & ocarina (redsteel) Wii backup w/ alt dol & WiiRD Retail & Backup forcing video modes Saving individual settings for games on DVD (only Wii as BC is loaded before any settings would be used) Display disc images for DVD games Loading GC games retail & backup (w/ working MIOS patch installed) I did change some stuff after testing GC so it might be broken. Theme stuff for the button is not tested and I'm not quite up to speed with ardi's changes to the theme stuff so it might not work. Changed images are not compressed or optimized.
451 lines
13 KiB
C++
451 lines
13 KiB
C++
/****************************************************************************
|
|
* DiscBrowser
|
|
* USB Loader GX 2009
|
|
*
|
|
* DiscBrowser.h
|
|
***************************************************************************/
|
|
#include "language/gettext.h"
|
|
#include "libwiigui/gui.h"
|
|
#include "libwiigui/gui_customoptionbrowser.h"
|
|
#include "prompts/PromptWindows.h"
|
|
#include "filelist.h"
|
|
#include "menu.h"
|
|
#include "usbloader/disc.h"
|
|
#include "usbloader/fstfile.h"
|
|
#include "usbloader/wdvd.h"
|
|
#include "main.h"
|
|
#include "sys.h"
|
|
#include "settings/cfg.h"
|
|
#include "memory.h"
|
|
#include "../wad/title.h"
|
|
#include "../patches/dvd_broadway.h"
|
|
|
|
#define BC 0x0000000100000100ULL
|
|
|
|
/*** Extern functions ***/
|
|
extern void ResumeGui();
|
|
extern void HaltGui();
|
|
|
|
/*** Extern variables ***/
|
|
extern GuiWindow * mainWindow;
|
|
extern u8 shutdown;
|
|
extern u8 reset;
|
|
extern u8 dvdMounted;
|
|
|
|
/********************************************************************************
|
|
*Disk Browser
|
|
*********************************************************************************/
|
|
int DiscBrowse(struct discHdr * header) {
|
|
bool exit = false;
|
|
int ret, choice;
|
|
u64 offset;
|
|
|
|
HaltGui();
|
|
if (!dvdMounted)
|
|
{
|
|
ret = Disc_SetUSB(header->id);
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not set USB."), tr("OK"));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
ret = Disc_Open();
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not open disc."), tr("OK"));
|
|
return ret;
|
|
}
|
|
|
|
ret = __Disc_FindPartition(&offset);
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not find a WBFS partition."), tr("OK"));
|
|
return ret;
|
|
}
|
|
|
|
ret = WDVD_OpenPartition(offset);
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not open WBFS partition"), tr("OK"));
|
|
return ret;
|
|
}
|
|
|
|
int *buffer = (int*)allocate_memory(0x20);
|
|
|
|
if (buffer == NULL) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
|
|
return -1;
|
|
}
|
|
|
|
ret = WDVD_Read(buffer, 0x20, 0x420);
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
|
|
return ret;
|
|
}
|
|
|
|
void *fstbuffer = allocate_memory(buffer[2]*4);
|
|
FST_ENTRY *fst = (FST_ENTRY *)fstbuffer;
|
|
|
|
if (fst == NULL) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
|
|
free(buffer);
|
|
return -1;
|
|
}
|
|
|
|
ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4);
|
|
|
|
if (ret < 0) {
|
|
ResumeGui();
|
|
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
|
|
free(buffer);
|
|
free(fstbuffer);
|
|
return ret;
|
|
}
|
|
ResumeGui();
|
|
free(buffer);
|
|
|
|
WDVD_Reset();
|
|
//Disc_SetUSB(NULL);
|
|
WDVD_ClosePartition();
|
|
|
|
u32 discfilecount = fst[0].filelen;
|
|
u32 dolfilecount = 0;
|
|
//int offsetselect[20];
|
|
|
|
customOptionList options3(discfilecount);
|
|
|
|
for (u32 i = 0; i < discfilecount; i++) {
|
|
|
|
//don't add files that aren't .dol to the list
|
|
int len = (strlen(fstfiles(fst, i)));
|
|
if (fstfiles(fst, i)[len-4] =='.' &&
|
|
fstfiles(fst, i)[len-3] =='d' &&
|
|
fstfiles(fst, i)[len-2] =='o' &&
|
|
fstfiles(fst, i)[len-1] =='l') {
|
|
options3.SetName(i, "%i", i);
|
|
options3.SetValue(i, fstfiles(fst, i));
|
|
//options3.SetName(i, fstfiles(fst, i));
|
|
|
|
dolfilecount++;
|
|
}
|
|
}
|
|
|
|
if (dolfilecount <= 0) {
|
|
WindowPrompt(tr("ERROR"), tr("No dol file found on disc."), tr("OK"));
|
|
free(fstbuffer);
|
|
return -1;
|
|
}
|
|
|
|
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
|
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
|
|
|
char imgPath[100];
|
|
|
|
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
|
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
|
|
snprintf(imgPath, sizeof(imgPath), "%sgamesettings_background.png", CFG.theme_path);
|
|
GuiImageData settingsbg(imgPath, settings_background_png);
|
|
|
|
GuiTrigger trigA;
|
|
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
|
|
GuiTrigger trigHome;
|
|
trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
|
|
GuiTrigger trigB;
|
|
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
|
|
|
|
GuiText titleTxt(get_title(header), 28, (GXColor) {0, 0, 0, 255});
|
|
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
|
titleTxt.SetPosition(12,40);
|
|
titleTxt.SetMaxWidth(356, GuiText::SCROLL);
|
|
|
|
GuiImage settingsbackground(&settingsbg);
|
|
GuiButton settingsbackgroundbtn(settingsbackground.GetWidth(), settingsbackground.GetHeight());
|
|
settingsbackgroundbtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
|
|
settingsbackgroundbtn.SetPosition(0, 0);
|
|
settingsbackgroundbtn.SetImage(&settingsbackground);
|
|
|
|
GuiText cancelBtnTxt(tr("Back"), 22, THEME.prompttext);
|
|
cancelBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
|
|
GuiImage cancelBtnImg(&btnOutline);
|
|
if (Settings.wsprompt == yes) {
|
|
cancelBtnTxt.SetWidescreen(CFG.widescreen);
|
|
cancelBtnImg.SetWidescreen(CFG.widescreen);
|
|
}
|
|
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
|
cancelBtn.SetScale(0.9);
|
|
cancelBtn.SetLabel(&cancelBtnTxt);
|
|
cancelBtn.SetTrigger(&trigB);
|
|
|
|
u8 scrollbaron = 0;
|
|
if (dolfilecount > 9)
|
|
scrollbaron = 1;
|
|
|
|
GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, dolfilecount>9?1:0, 200);
|
|
optionBrowser3.SetPosition(0, 90);
|
|
optionBrowser3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
|
|
|
HaltGui();
|
|
GuiWindow w(screenwidth, screenheight);
|
|
w.Append(&settingsbackgroundbtn);
|
|
w.Append(&titleTxt);
|
|
w.Append(&cancelBtn);
|
|
w.Append(&optionBrowser3);
|
|
|
|
mainWindow->Append(&w);
|
|
|
|
ResumeGui();
|
|
while (!exit) {
|
|
VIDEO_WaitVSync();
|
|
|
|
if (shutdown == 1)
|
|
Sys_Shutdown();
|
|
if (reset == 1)
|
|
Sys_Reboot();
|
|
|
|
ret = optionBrowser3.GetClickedOption();
|
|
|
|
if (ret > 0) {
|
|
char temp[100];
|
|
strlcpy(temp, fstfiles(fst, ret), sizeof(temp));
|
|
choice = WindowPrompt(temp, tr("Load this dol as alternate dol?"), tr("OK"), tr("Cancel"));
|
|
if (choice) {
|
|
//ret = offsetselect[ret];
|
|
strlcpy(alternatedname, temp, sizeof(alternatedname));
|
|
exit = true;
|
|
}
|
|
}
|
|
|
|
if (cancelBtn.GetState() == STATE_CLICKED) {
|
|
ret = 696969;
|
|
exit = true;
|
|
}
|
|
}
|
|
|
|
HaltGui();
|
|
mainWindow->Remove(&w);
|
|
ResumeGui();
|
|
|
|
//free not needed list buffer anymore
|
|
free(fstbuffer);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int autoSelectDol(const char *id, bool force) {
|
|
|
|
char id4[10];
|
|
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
|
|
|
|
////// games that can be forced (always need alt dol)
|
|
|
|
//Boogie
|
|
if (strcmp(id,"RBOP69") == 0) return 675;//previous value was 657
|
|
if (strcmp(id,"RBOE69") == 0) return 675;//starstremr
|
|
|
|
//Fifa 08
|
|
if (strcmp(id,"RF8E69") == 0) return 439;//from isostar
|
|
if (strcmp(id,"RF8P69") == 0) return 463;//from isostar
|
|
if (strcmp(id,"RF8X69") == 0) return 464;//from isostar
|
|
|
|
//Madden NFL07
|
|
if (strcmp(id,"RMDP69") == 0) return 39;//from isostar
|
|
|
|
//Madden NFL08
|
|
if (strcmp(id,"RNFP69") == 0) return 1079;//from isostar
|
|
|
|
//Medal of Honor: Heroes 2
|
|
if (strcmp(id,"RM2X69") == 0)return 601;//dj_skual
|
|
if (strcmp(id,"RM2P69") == 0)return 517;//MZottel
|
|
if (strcmp(id,"RM2E69") == 0) return 492;//Old8oy
|
|
|
|
//Mortal Kombat
|
|
if (strcmp(id,"RKMP5D") == 0) return 290;//from isostar
|
|
if (strcmp(id,"RKME5D") == 0) return 290;//starstremr
|
|
|
|
//NBA 08
|
|
if (strcmp(id,"RNBX69") == 0) return 964;//from isostar
|
|
|
|
//Pangya! Golf with Style
|
|
if (strcmp(id,"RPYP9B") == 0) return 12490;//from isostar
|
|
|
|
//Redsteel
|
|
if (strcmp(id,"REDP41") == 0) return 1957;//from isostar
|
|
if (strcmp(id,"REDE41") == 0) return 1957;//starstremr
|
|
|
|
//SSX
|
|
if (strcmp(id,"RSXP69") == 0) return 377;//previous value was 337
|
|
if (strcmp(id,"RSXE69") == 0) return 377;//previous value was 337
|
|
|
|
//Wii Sports Resort, needs alt dol one time only, to show the Motion Plus video
|
|
//if (strcmp(id,"RZTP01") == 0 && CheckForSave(id4)==0) return 952;//from isostar
|
|
//if (strcmp(id,"RZTE01") == 0 && CheckForSave(id4)==0) return 674;//from starstremr
|
|
//as well as Grand Slam Tennis, Tiger Woods 10, Virtual Tennis 2009
|
|
|
|
///// games that can't be forced (alt dol is not always needed)
|
|
if (!force) {
|
|
|
|
//Grand Slam Tennis
|
|
if (strcmp(id,"R5TP69") == 0) return 1493;//from isostar
|
|
if (strcmp(id,"R5TE69") == 0) return 1493;//starstremr
|
|
|
|
//Indiana Jones and the Staff of Kings (Fate of Atlantis)
|
|
if (strcmp(id,"RJ8P64") == 0) return 8;//from isostar
|
|
if (strcmp(id,"RJ8E64") == 0) return 8;//starstremr
|
|
|
|
//Medal of Honor Heroes
|
|
if (strcmp(id,"RMZX69") == 0) return 492;//from isostar
|
|
if (strcmp(id,"RMZP69") == 0) return 492;//from isostar
|
|
if (strcmp(id,"RMZE69") == 0) return 492;//starstremr
|
|
|
|
//Metal Slug Anthology
|
|
if (strcmp(id,"RMLP7U") == 0) return 56;//from isostar
|
|
|
|
//The House Of The Dead 2 & 3 Return
|
|
if (strcmp(id,"RHDP8P") == 0) return 149;//from isostar
|
|
if (strcmp(id,"RHDE8P") == 0) return 149;//starstremr
|
|
|
|
//Tiger Woods 10
|
|
if (strcmp(id,"R9OP69") == 0) return 1991;//from isostar
|
|
if (strcmp(id,"R9OE69") == 0) return 1973;//starstremr
|
|
|
|
//Virtual Tennis 2009
|
|
if (strcmp(id,"RVUP8P") == 0) return 16426;//from isostar
|
|
if (strcmp(id,"RVUE8P") == 0) return 16405;//from isostar
|
|
|
|
//Wii Sports Resort
|
|
if (strcmp(id,"RZTP01") == 0) return 952;//from isostar
|
|
if (strcmp(id,"RZTE01") == 0) return 674;//from starstremr
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int autoSelectDolMenu(const char *id, bool force) {
|
|
|
|
char id4[10];
|
|
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
|
|
|
|
/*
|
|
switch (CheckForSave(id4)) {
|
|
case 0:
|
|
WindowPrompt("NO save",0,tr("Ok"));
|
|
break;
|
|
case 1:
|
|
WindowPrompt("save",0,tr("Ok"));
|
|
break;
|
|
default:
|
|
char test[10];
|
|
sprintf(test,"%d",CheckForSave(id4));
|
|
WindowPrompt(test,0,tr("Ok"));
|
|
break;
|
|
}
|
|
return -1;
|
|
*/
|
|
|
|
//Metroid Prime Trilogy
|
|
if (strcmp(id,"R3ME01") == 0) {
|
|
//do not use any alt dol if there is no save game in the nand
|
|
/*
|
|
if (CheckForSave(id4)==0 && force) {
|
|
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
|
|
return -1;
|
|
}
|
|
*/
|
|
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
|
|
switch (choice) {
|
|
case 1:
|
|
choice = 780;
|
|
break;
|
|
case 2:
|
|
choice = 781;
|
|
break;
|
|
case 3:
|
|
choice = 782;
|
|
break;
|
|
default: // no alt dol
|
|
choice = 0;
|
|
break;
|
|
}
|
|
return choice;
|
|
}
|
|
if (strcmp(id,"R3MP01") == 0) {
|
|
/*
|
|
if (CheckForSave(id4)==0 && force) {
|
|
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
|
|
return -1;
|
|
}
|
|
*/
|
|
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
|
|
switch (choice) {
|
|
case 1:
|
|
choice = 782;
|
|
break;
|
|
case 2:
|
|
choice = 783;
|
|
break;
|
|
case 3:
|
|
choice = 784;
|
|
break;
|
|
default: // no alt dol
|
|
choice = 0;
|
|
break;
|
|
}
|
|
return choice;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/********************************************************************************
|
|
* Mount a DVD, get the type and ID.
|
|
*********************************************************************************/
|
|
static vu32 dvddone = 0;
|
|
static dvddiskid *g_diskID = (dvddiskid*)0x80000000;
|
|
void __dvd_readidcb(s32 result)
|
|
{
|
|
dvddone = result;
|
|
}
|
|
|
|
u8 DiscMount(char *id) {
|
|
int ret;
|
|
char gameidbuffer[8];
|
|
HaltGui();
|
|
memset((char*)0x80000000, 0, 6);
|
|
|
|
ret = bwDVD_LowInit();
|
|
dvddone = 0;
|
|
ret = bwDVD_LowReset(__dvd_readidcb);
|
|
while(ret>=0 && dvddone==0);
|
|
|
|
dvddone = 0;
|
|
ret = bwDVD_LowReadID(g_diskID,__dvd_readidcb);
|
|
while(ret>=0 && dvddone==0);
|
|
|
|
memset(gameidbuffer, 0, 8);
|
|
memcpy(gameidbuffer, (char*)0x80000000, 6);
|
|
strcpy(id,gameidbuffer);
|
|
if(gameidbuffer[1] == 0 &&
|
|
gameidbuffer[2] == 0 &&
|
|
gameidbuffer[3] == 0 &&
|
|
gameidbuffer[4] == 0 &&
|
|
gameidbuffer[5] == 0 &&
|
|
gameidbuffer[6] == 0)
|
|
{
|
|
ResumeGui();
|
|
return 0;
|
|
}
|
|
if(*((u32 *) 0x8000001C) == 0xC2339F3D){
|
|
ResumeGui();
|
|
return 2;
|
|
}
|
|
ResumeGui();
|
|
return 1;
|
|
}
|