diff --git a/source/fatmounter.c b/source/fatmounter.c index 5b97167e..6c87894d 100644 --- a/source/fatmounter.c +++ b/source/fatmounter.c @@ -47,7 +47,7 @@ sec_t fs_ntfs_sec = 0; int USBDevice_Init() { #ifdef DEBUG_FAT - gprintf( "\nUSBDevice_Init()" ); + gprintf( "USBDevice_Init()" ); #endif //closing all open Files write back the cache and then shutdown em! fatUnmount( "USB:/" ); @@ -59,7 +59,7 @@ int USBDevice_Init() if ( !fatMount( "USB", &__io_usbstorage2, 0, CACHE, SECTORS ) ) { #ifdef DEBUG_FAT - gprintf( ":-1" ); + gprintf( ":-1\n" ); #endif return -1; } @@ -68,7 +68,7 @@ int USBDevice_Init() fat_usb_mount = 1; fat_usb_sec = _FAT_startSector; #ifdef DEBUG_FAT - gprintf( ":0" ); + gprintf( ":0\n" ); #endif return 0; } @@ -76,13 +76,16 @@ int USBDevice_Init() void USBDevice_deInit() { #ifdef DEBUG_FAT - gprintf( "\nUSBDevice_deInit()" ); + gprintf( "USBDevice_deInit(): " ); #endif //closing all open Files write back the cache and then shutdown em! fatUnmount( "USB:/" ); fat_usb_mount = 0; fat_usb_sec = 0; +#ifdef DEBUG_FAT + gprintf( "ok\n" ); +#endif } int WBFSDevice_Init( u32 sector ) @@ -130,7 +133,7 @@ int isInserted( const char *path ) int SDCard_Init() { #ifdef DEBUG_FAT - gprintf( "\nSDCard_Init()" ); + gprintf( "SDCard_Init()" ); #endif //closing all open Files write back the cache and then shutdown em! fatUnmount( "SD:/" ); @@ -140,7 +143,7 @@ int SDCard_Init() fat_sd_mount = MOUNT_SD; fat_sd_sec = _FAT_startSector; #ifdef DEBUG_FAT - gprintf( ":1" ); + gprintf( ":1\n" ); #endif return 1; } @@ -149,12 +152,12 @@ int SDCard_Init() fat_sd_mount = MOUNT_SDHC; fat_sd_sec = _FAT_startSector; #ifdef DEBUG_FAT - gprintf( ":1" ); + gprintf( ":1\n" ); #endif return 1; } #ifdef DEBUG_FAT - gprintf( ":-1" ); + gprintf( ":-1\n" ); #endif return -1; } @@ -162,13 +165,16 @@ int SDCard_Init() void SDCard_deInit() { #ifdef DEBUG_FAT - gprintf( "\nSDCard_deInit()" ); + gprintf( "SDCard_deInit(): " ); #endif //closing all open Files write back the cache and then shutdown em! fatUnmount( "SD:/" ); fat_sd_mount = MOUNT_NONE; fat_sd_sec = 0; +#ifdef DEBUG_FAT + gprintf( "ok\n" ); +#endif } void ntfsInit(); diff --git a/source/gecko.c b/source/gecko.c index c3f027b1..e07d49c1 100644 --- a/source/gecko.c +++ b/source/gecko.c @@ -14,7 +14,7 @@ void gprintf( const char *str, ... ) { if ( !( geckoinit ) )return; - char astr[4096]; + char astr[ 0x100 ]; va_list ap; va_start( ap, str ); @@ -23,8 +23,8 @@ void gprintf( const char *str, ... ) va_end( ap ); - //usb_sendbuffer( 1, astr, strlen( astr ) ); - usb_sendbuffer_safe( 1, astr, strlen(astr) ); + usb_sendbuffer( 1, astr, strlen( astr ) ); + //usb_sendbuffer_safe( 1, astr, strlen(astr) ); } bool InitGecko() diff --git a/source/libwiigui/gui_customoptionbrowser.cpp b/source/libwiigui/gui_customoptionbrowser.cpp index 38388464..ec75f81b 100644 --- a/source/libwiigui/gui_customoptionbrowser.cpp +++ b/source/libwiigui/gui_customoptionbrowser.cpp @@ -104,10 +104,10 @@ void customOptionList::SetValue( int i, const char *format, ... ) if ( i >= 0 && i < length ) { - char *tmp = 0; + char *tmp = 0; va_list va; va_start( va, format ); - vasprintf( &tmp, format, va ); + vasprintf( &tmp, format, va ); va_end( va ); if ( tmp ) diff --git a/source/main.cpp b/source/main.cpp index cf9008ea..0841321c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -60,6 +60,7 @@ extern char headlessID[8]; NandTitle titles; PartList partitions; + int main( int argc, char *argv[] ) { MEM2_init( 48 ); diff --git a/source/menu.cpp b/source/menu.cpp index ba36d4ad..890a295a 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -439,6 +439,7 @@ int MainMenu( int menu ) alternatedoloffset = game_cfg->alternatedolstart; } reloadblock = game_cfg->iosreloadblock; + returnToLoaderGV = game_cfg->returnTo; } else { @@ -462,6 +463,7 @@ int MainMenu( int menu ) alternatedoloffset = 0; } reloadblock = off; + returnToLoaderGV = 1; } int ios2; @@ -667,9 +669,17 @@ int MainMenu( int menu ) vipatch = 0; break; } + + u32 channel = 0; + if( returnToLoaderGV ) + { + int idx = titles.FindU32( Settings.returnTo ); + if( idx >= 0 ) + channel = TITLE_LOWER( titles.At( idx ) ); + } gprintf( "\tDisc_wiiBoot\n" ); - ret = Disc_WiiBoot( videoselected, cheat, vipatch, countrystrings, errorfixer002, alternatedol, alternatedoloffset ); + ret = Disc_WiiBoot( videoselected, cheat, vipatch, countrystrings, errorfixer002, alternatedol, alternatedoloffset, channel ); if ( ret < 0 ) { Sys_LoadMenu(); diff --git a/source/menu/menu_disclist.cpp b/source/menu/menu_disclist.cpp index a60d66c3..b6404cb6 100644 --- a/source/menu/menu_disclist.cpp +++ b/source/menu/menu_disclist.cpp @@ -7,6 +7,7 @@ #include "network/networkops.h" #include "prompts/gameinfo.h" #include "prompts/DiscBrowser.h" +#include "prompts/TitleBrowser.h" #include "settings/Settings.h" #include "wpad.h" #include "sys.h" diff --git a/source/patches/gamepatches.c b/source/patches/gamepatches.c index 18df024e..e1c21bc6 100644 --- a/source/patches/gamepatches.c +++ b/source/patches/gamepatches.c @@ -3,6 +3,7 @@ #include #include "dolpatcher.h" #include "wip.h" +#include "gecko.h" /** Anti 002 fix for IOS 249 rev > 12 thanks to WiiPower **/ bool Anti_002_fix( u8 * Address, int Size ) @@ -280,3 +281,137 @@ void VideoModePatcher( u8 * dst, int len, u8 videoSelected ) Search_and_patch_Video_Modes( dst, len, table ); } } + +//giantpune's magic super patch to return to channels +bool PatchReturnTo( void *Address, int Size, u32 id ) { + if( !id )return 0; + //new __OSLoadMenu() (SM2.0 and higher) + u8 SearchPattern[ 12 ] = { 0x38, 0x80, 0x00, 0x02, 0x38, 0x60, 0x00, 0x01, 0x38, 0xa0, 0x00, 0x00 }; + + //old _OSLoadMenu() (used in launch games) + u8 SearchPatternB[ 12 ] = { 0x38, 0xC0, 0x00, 0x02, 0x38, 0xA0, 0x00, 0x01, 0x38, 0xE0, 0x00, 0x00 }; + + //identifier for the safe place + u8 SearchPattern2[ 12 ] = { 0x4D, 0x65, 0x74, 0x72, 0x6F, 0x77, 0x65, 0x72, 0x6B, 0x73, 0x20, 0x54 }; + + + int found = 0; + int patched = 0; + u8 oldSDK = 0; + u32 ad[ 4 ] = { 0, 0, 0, 0 }; + + void *Addr = Address; + void *Addr_end = Address+Size; + + while (Addr <= Addr_end - 12 ) { + //find a safe place or the patch to hang out + if ( ! ad[ 3 ] && memcmp( Addr, SearchPattern2, 12 )==0 ) { + ad[ 3 ] = (u32)Addr + 0x30; + //gprintf("found a safe place @ %08x\n", ad[ 3 ]); + //hexdump( Addr, 0x50 ); + } + //find __OSLaunchMenu() and remember some addresses in it + else if ( memcmp( Addr, SearchPattern, 12 )==0 ) { + ad[ found++ ] = (u32)Addr; + } + else if ( ad[ 0 ] && memcmp( Addr, SearchPattern, 8 )==0 ) //after the first match is found, only search the first 8 bytes for the other 2 + { + if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr; + else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr; + if( found >= 3 )break; + } + Addr += 4; + } + //check for the older-ass version of the SDK + if( found < 3 && ad[ 3 ] ) + { + Addr = Address; + ad[ 0 ] = 0; ad[ 1 ] = 0; + ad[ 2 ] = 0; + found = 0; + oldSDK = 1; + + while (Addr <= Addr_end - 12 ) { + //find __OSLaunchMenu() and remember some addresses in it + if ( memcmp( Addr, SearchPatternB, 12 )==0 ) { + ad[ found++ ] = (u32)Addr; + } + else if ( ad[ 0 ] && memcmp( Addr, SearchPatternB, 8 ) == 0 ) //after the first match is found, only search the first 8 bytes for the other 2 + { + if( !ad[ 1 ] ) ad[ found++ ] = (u32)Addr; + else if( !ad[ 2 ] ) ad[ found++ ] = (u32)Addr; + if( found >= 3 )break; + } + Addr += 4; + } + } + + //if the function is found and if it is not too far into the main.dol + if( found == 3 && ( ad[ 2 ] - ad[ 3 ] < 0x1000001 ) && ad[ 3 ] ) + { + //gprintf("patch __OSLaunchMenu( 0x00010001, 0x%08x )\n", id); + u32 nop = 0x60000000; + + //the magic that writes the TID to the registers + u8 jump[ 20 ] = { 0x3C, 0x60, 0x00, 0x01, 0x60, 0x63, 0x00, 0x01, + 0x3C, 0x80, 0x4A, 0x4F, 0x60, 0x84, 0x44, 0x49, + 0x4E, 0x80, 0x00, 0x20 }; + if( oldSDK ) + { + jump[ 1 ] = 0xA0; //3CA00001 60A50001 + jump[ 5 ] = 0xA5; //3CC04A4F 60C64449 + jump[ 9 ] = 0xC0; + jump[ 13 ] = 0xC6; + } + //patch the thing to use the new TID + jump[ 10 ] = (u8)( id >> 24 ); + jump[ 11 ] = (u8)( id >> 16 ); + jump[ 14 ] = (u8)( id >> 8 ); + jump[ 15 ] = (u8)id; + + void* addr = (u32*)ad[ 3 ]; + + //write new stuff to memory main.dol in a unused part of the main.dol + memcpy( addr, jump, sizeof( jump ) ); + + //ES_GetTicketViews() + u32 newval = ( ad[ 3 ] - ad[ 0 ] ); + newval &= 0x03FFFFFC; + newval |= 0x48000001; + addr = (u32*)ad[ 0 ]; + memcpy( addr, &newval, sizeof( u32 ) ); + memcpy( addr + 4, &nop, sizeof( u32 ) ); + //gprintf("\t%p -> %08x\n", addr, newval ); + + //ES_GetTicketViews() again + newval = ( ad[ 3 ] - ad[ 1 ] ); + newval &= 0x03FFFFFC; + newval |= 0x48000001; + addr = (u32*)ad[ 1 ]; + memcpy( addr, &newval, sizeof( u32 ) ); + memcpy( addr + 4, &nop, sizeof( u32 ) ); + //gprintf("\t%p -> %08x\n", addr, newval ); + + //ES_LaunchTitle() + newval = ( ad[ 3 ] - ad[ 2 ] ); + newval &= 0x03FFFFFC; + newval |= 0x48000001; + addr = (u32*)ad[ 2 ]; + memcpy( addr, &newval, sizeof( u32 ) ); + memcpy( addr + 4, &nop, sizeof( u32 ) ); + //gprintf("\t%p -> %08x\n", addr, newval ); + + patched = 1; + } + else + { + gprintf("not patched\n"); + gprintf("found %d addresses\n", found); + int i; + for( i = 0; i< 4; i++) + gprintf("ad[ %d ]: %08x\n", i, ad[ i ] ); + gprintf("offset : %08x\n", ad[ 2 ] - ad[ 3 ] ); + + } + return patched; +} diff --git a/source/patches/gamepatches.h b/source/patches/gamepatches.h index fbe6f3a8..a5769157 100644 --- a/source/patches/gamepatches.h +++ b/source/patches/gamepatches.h @@ -8,5 +8,6 @@ bool NSMBPatch( u8 * Address, int Size ); bool PoPPatch(); bool Search_and_patch_Video_Modes( u8 * Address, u32 Size, GXRModeObj* Table[] ); void VideoModePatcher( u8 * dst, int len, u8 videoSelected ); +bool PatchReturnTo( void *Address, int Size, u32 id ); #endif diff --git a/source/prompts/TitleBrowser.cpp b/source/prompts/TitleBrowser.cpp index 2b60d15a..4e97432f 100644 --- a/source/prompts/TitleBrowser.cpp +++ b/source/prompts/TitleBrowser.cpp @@ -51,8 +51,191 @@ extern wchar_t *gameFilter; /******************************************************************************** * TitleBrowser- opens a browser with a list of installed Titles -* relies on code from any title deleter. *********************************************************************************/ +bool TitleSelector( char output[] ) +{ + gprintf("TitleSelector()\n"); + + u32 num_titles; + s32 r = -1; + bool ret = false; + u64 *titleList = NULL; + + ISFS_Initialize();//initialize for "titles.Exists()" + + // Get count of titles of the good titles + num_titles = titles.SetType( 0x10001 ); + u32 n = num_titles; + //gprintf("num_titles: %u\n", num_titles ); + for ( u32 i = 0; i < n; i++ ) + { + u64 tid = titles.Next(); + if ( !tid ) + { + break; + } + + //remove ones not actually installed on the nand + if ( !titles.Exists( tid ) ) + { + num_titles--; + } + } + //gprintf("num_titles: %u\n", num_titles ); + + //make a list of just the tids we are adding to the titlebrowser + titleList = ( u64* )memalign( 32, num_titles * sizeof( u64 ) ); + if ( !titleList ) + { + gprintf( "TitleLister(): out of memory!\n" ); + return false; + } + customOptionList options4( num_titles + 1 ); + //write the titles on the option browser + + u32 i = 0; + titles.SetType( 0x10001 ); + while ( i < num_titles ) + { + u64 tid = titles.Next(); + if ( !tid ) + { + gprintf( "shit happened\n" ); + break; + } + + if ( !titles.Exists( tid ) ) + { + continue; + } + + char id[ 5 ]; + titles.AsciiTID( tid, ( char* )&id ); + + char* name = titles.NameOf( tid ); + //gprintf("%016llx: %s: %s\n%p\t%p\n", tid, id, name, &id, name ); + + options4.SetName( i, "%s", id ); + options4.SetValue( i, "%s", name ? titles.NameOf( tid ) : tr( "Unknown" ) ); + titleList[ i ] = tid; + i++; + } + // gprintf("i: %u\n", i ); + //hexdump( titleList, num_titles * sizeof( u64 ) ); + + options4.SetName( i, " " ); + options4.SetValue( i, "%s", tr( "Clear" ) ); + + ISFS_Deinitialize(); + + bool exit = false; + + GuiSound btnSoundOver( button_over_pcm, button_over_pcm_size, Settings.sfxvolume ); + // because destroy GuiSound must wait while sound playing is finished, we use a global sound + if ( !btnClick2 ) btnClick2 = new GuiSound( button_click2_pcm, button_click2_pcm_size, 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 ); + + GuiImage settingsbackground( &settingsbg ); + GuiButton settingsbackgroundbtn( settingsbackground.GetWidth(), settingsbackground.GetHeight() ); + settingsbackgroundbtn.SetAlignment( ALIGN_LEFT, ALIGN_TOP ); + settingsbackgroundbtn.SetPosition( 0, 0 ); + settingsbackgroundbtn.SetImage( &settingsbackground ); + + GuiTrigger trigA; + trigA.SetSimpleTrigger( -1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A ); + GuiTrigger trigB; + trigB.SetButtonOnlyTrigger( -1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B ); + + 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, btnClick2, 1 ); + cancelBtn.SetLabel( &cancelBtnTxt ); + cancelBtn.SetTrigger( &trigB ); + + u8 scrollbaron = 0; + if ( num_titles + 1 > 9 ) + scrollbaron = 1; + + GuiCustomOptionBrowser optionBrowser4( 396, 280, &options4, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, scrollbaron, 200 ); + optionBrowser4.SetPosition( 0, 90 ); + optionBrowser4.SetAlignment( ALIGN_CENTRE, ALIGN_TOP ); + + GuiTrigger trigZ; + trigZ.SetButtonOnlyTrigger( -1, WPAD_NUNCHUK_BUTTON_Z | WPAD_CLASSIC_BUTTON_ZL, PAD_TRIGGER_Z ); + + GuiButton screenShotBtn( 0, 0 ); + screenShotBtn.SetPosition( 0, 0 ); + screenShotBtn.SetTrigger( &trigZ ); + + + + HaltGui(); + GuiWindow w( screenwidth, screenheight ); + w.Append( &settingsbackgroundbtn ); + w.Append( &screenShotBtn ); + w.Append( &cancelBtn ); + w.Append( &optionBrowser4 ); + mainWindow->SetState( STATE_DISABLED ); + mainWindow->Append( &w ); + + ResumeGui(); + + while ( !exit ) + { + VIDEO_WaitVSync(); + + if ( shutdown == 1 ) Sys_Shutdown(); + if ( reset == 1 ) Sys_Reboot(); + + r = optionBrowser4.GetClickedOption(); + + if ( r > -1 ) + { //if a click happened + if( r < num_titles ) + { + u64 tid = titleList[ r ]; + sprintf( output, "%08x", TITLE_LOWER( tid ) ); + } + else + output[ 0 ] = 0; + ret = true; + exit = true; + } + + else if ( cancelBtn.GetState() == STATE_CLICKED ) + { + //break the loop and end the function + exit = true; + } + else if ( screenShotBtn.GetState() == STATE_CLICKED ) + { + screenShotBtn.ResetState(); + ScreenShot(); + } + } + + HaltGui(); + mainWindow->SetState( STATE_DEFAULT ); + mainWindow->Remove( &w ); + free( titleList ); + ResumeGui(); + + return ret; +} + + int TitleBrowser() { @@ -68,17 +251,17 @@ int TitleBrowser() u32 n = num_titles; for ( u32 i = 0; i < n; i++ ) { - u64 tid = titles.Next(); - if ( !tid ) - { - break; - } + u64 tid = titles.Next(); + if ( !tid ) + { + break; + } - //remove ones not actually installed on the nand - if ( !titles.Exists( tid ) ) - { - num_titles--; - } + //remove ones not actually installed on the nand + if ( !titles.Exists( tid ) ) + { + num_titles--; + } } // Get count of system titles @@ -86,31 +269,31 @@ int TitleBrowser() n = num_sys_titles; for ( u32 i = 0; i < n; i++ ) { - u64 tid = titles.Next(); - if ( !tid ) - { - break; - } - //these can't be booted anyways - if ( TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641 ) - { - num_sys_titles--; - continue; - } + u64 tid = titles.Next(); + if ( !tid ) + { + break; + } + //these can't be booted anyways + if ( TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641 ) + { + num_sys_titles--; + continue; + } - //these aren't installed on the nand - if ( !titles.Exists( tid ) ) - { - num_sys_titles--; - } + //these aren't installed on the nand + if ( !titles.Exists( tid ) ) + { + num_sys_titles--; + } } //make a list of just the tids we are adding to the titlebrowser titleList = ( u64* )memalign( 32, ( num_titles + num_sys_titles ) * sizeof( u64 ) ); if ( !titleList ) { - gprintf( "TitleBrowser(): out of memory!\n" ); - return -1; + gprintf( "TitleBrowser(): out of memory!\n" ); + return -1; } customOptionList options3( num_titles + num_sys_titles + 1 ); //write the titles on the option browser @@ -120,54 +303,54 @@ int TitleBrowser() //first add the good stuff while ( i < num_titles ) { - u64 tid = titles.Next(); - if ( !tid ) - { - gprintf( "shit happened3\n" ); - break; - } - //gprintf("[ %u] tid: %016llx\t%s\n", i, tid, titles.NameOf( tid ) ); + u64 tid = titles.Next(); + if ( !tid ) + { + gprintf( "shit happened3\n" ); + break; + } + //gprintf("[ %u] tid: %016llx\t%s\n", i, tid, titles.NameOf( tid ) ); - if ( !titles.Exists( tid ) ) - { - continue; - } + if ( !titles.Exists( tid ) ) + { + continue; + } - char id[ 5 ]; - titles.AsciiTID( tid, ( char* )&id ); + char id[ 5 ]; + titles.AsciiTID( tid, ( char* )&id ); - char* name = titles.NameOf( tid ); + char* name = titles.NameOf( tid ); - options3.SetName( i, "%s", id ); - options3.SetValue( i, "%s", name ? titles.NameOf( tid ) : "Unknown" ); - titleList[ i ] = tid; - i++; + options3.SetName( i, "%s", id ); + options3.SetValue( i, "%s", name ? titles.NameOf( tid ) : tr( "Unknown" ) ); + titleList[ i ] = tid; + i++; } titles.SetType( 0x10002 ); while ( i < num_sys_titles + num_titles ) { - u64 tid = titles.Next(); - if ( !tid ) - { - break; - } - if ( TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641 ) - continue; + u64 tid = titles.Next(); + if ( !tid ) + { + break; + } + if ( TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641 ) + continue; - if ( !titles.Exists( tid ) ) - { - continue; - } + if ( !titles.Exists( tid ) ) + { + continue; + } - char id[ 5 ]; - titles.AsciiTID( tid, ( char* )&id ); - char* name = titles.NameOf( tid ); + char id[ 5 ]; + titles.AsciiTID( tid, ( char* )&id ); + char* name = titles.NameOf( tid ); - options3.SetName( i, "%s", id ); - options3.SetValue( i, "%s", name ? titles.NameOf( tid ) : "Unknown" ); - titleList[ i ] = tid; - i++; + options3.SetName( i, "%s", id ); + options3.SetValue( i, "%s", name ? titles.NameOf( tid ) : tr( "Unknown" ) ); + titleList[ i ] = tid; + i++; } ISFS_Deinitialize(); @@ -175,15 +358,15 @@ int TitleBrowser() if ( i == num_titles + num_sys_titles ) { - options3.SetName( i, " " ); - options3.SetValue( i, "%s", tr( "Wii Settings" ) ); + options3.SetName( i, " " ); + options3.SetValue( i, "%s", tr( "Wii Settings" ) ); } bool exit = false; int total = num_titles + num_sys_titles; if ( IsNetworkInit() ) - ResumeNetworkWait(); + ResumeNetworkWait(); GuiSound btnSoundOver( button_over_pcm, button_over_pcm_size, Settings.sfxvolume ); // because destroy GuiSound must wait while sound playing is finished, we use a global sound @@ -220,8 +403,8 @@ int TitleBrowser() GuiImage cancelBtnImg( &btnOutline ); if ( Settings.wsprompt == yes ) { - cancelBtnTxt.SetWidescreen( CFG.widescreen ); - cancelBtnImg.SetWidescreen( CFG.widescreen ); + cancelBtnTxt.SetWidescreen( CFG.widescreen ); + cancelBtnImg.SetWidescreen( CFG.widescreen ); } GuiButton cancelBtn( &cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2, 1 ); cancelBtn.SetScale( 0.9 ); @@ -230,7 +413,7 @@ int TitleBrowser() u8 scrollbaron = 0; if ( total + 1 > 9 ) - scrollbaron = 1; + scrollbaron = 1; GuiCustomOptionBrowser optionBrowser3( 396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, scrollbaron, 200 ); optionBrowser3.SetPosition( 0, 90 ); @@ -241,7 +424,7 @@ int TitleBrowser() GuiImage wifiImg( &wifiImgData ); if ( Settings.wsprompt == yes ) { - wifiImg.SetWidescreen( CFG.widescreen ); + wifiImg.SetWidescreen( CFG.widescreen ); } GuiButton wifiBtn( wifiImg.GetWidth(), wifiImg.GetHeight() ); wifiBtn.SetImage( &wifiImg ); @@ -273,269 +456,267 @@ int TitleBrowser() while ( !exit ) { - VIDEO_WaitVSync(); + VIDEO_WaitVSync(); - if ( shutdown == 1 ) Sys_Shutdown(); - if ( reset == 1 ) Sys_Reboot(); + if ( shutdown == 1 ) Sys_Shutdown(); + if ( reset == 1 ) Sys_Reboot(); - else if ( wifiBtn.GetState() == STATE_CLICKED ) - { - ResumeNetworkWait(); - wifiBtn.ResetState(); - } + else if ( wifiBtn.GetState() == STATE_CLICKED ) + { + ResumeNetworkWait(); + wifiBtn.ResetState(); + } - if ( IsNetworkInit() ) - { - wifiBtn.SetAlpha( 255 ); - } + if ( IsNetworkInit() ) + { + wifiBtn.SetAlpha( 255 ); + } - ret = optionBrowser3.GetClickedOption(); + ret = optionBrowser3.GetClickedOption(); - if ( ret > -1 ) - { //if a click happened + if ( ret > -1 ) + { //if a click happened - if ( ret < total ) - { - //set the title's name, number, ID to text - char text[ 0x100 ]; - char id[ 5 ]; - titles.AsciiTID( titleList[ ret ], ( char* )&id ); + if ( ret < total ) + { + //set the title's name, number, ID to text + char text[ 0x100 ]; + char id[ 5 ]; + titles.AsciiTID( titleList[ ret ], ( char* )&id ); - snprintf( text, sizeof( text ), "%s : %s", id, titles.NameOf( titleList[ ret ] ) ); + snprintf( text, sizeof( text ), "%s : %s", id, titles.NameOf( titleList[ ret ] ) ); - //prompt to boot selected title - if ( WindowPrompt( tr( "Boot?" ), text, tr( "OK" ), tr( "Cancel" ) ) ) - { //if they say yes - CloseXMLDatabase(); - ExitGUIThreads(); - ShutdownAudio(); - StopGX(); - WII_Initialize(); - WII_LaunchTitle( titleList[ ret ] ); - //this really shouldn't be needed because the title will be booted - exit = true; - break; - } - else - { - //if they said no to booting the title - ret = -1; - optionBrowser3.ResetState(); - } + //prompt to boot selected title + if ( WindowPrompt( tr( "Boot?" ), text, tr( "OK" ), tr( "Cancel" ) ) ) + { //if they say yes + CloseXMLDatabase(); + ExitGUIThreads(); + ShutdownAudio(); + StopGX(); + WII_Initialize(); + WII_LaunchTitle( titleList[ ret ] ); + //this really shouldn't be needed because the title will be booted + exit = true; + break; + } + else + { + //if they said no to booting the title + ret = -1; + optionBrowser3.ResetState(); + } - } - else if ( ret == total ) - { //if they clicked to go to the wii settings - CloseXMLDatabase(); - ExitGUIThreads(); - ShutdownAudio(); - StopGX(); - WII_Initialize(); - WII_ReturnToSettings(); - } - } + } + else if ( ret == total ) + { //if they clicked to go to the wii settings + CloseXMLDatabase(); + ExitGUIThreads(); + ShutdownAudio(); + StopGX(); + WII_Initialize(); + WII_ReturnToSettings(); + } + } #if 0 - if ( infilesize > 0 ) - { + if ( infilesize > 0 ) + { - char filesizetxt[50]; - char temp[50]; - char filepath[100]; + char filesizetxt[50]; + char temp[50]; + char filepath[100]; // u32 read = 0; - //make sure there is a folder for this to be saved in - struct stat st; - snprintf( filepath, sizeof( filepath ), "%s/wad/", bootDevice ); - if ( stat( filepath, &st ) != 0 ) - { - if ( subfoldercreate( filepath ) != 1 ) - { - WindowPrompt( tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ) ); - } - } - snprintf( filepath, sizeof( filepath ), "%s/wad/tmp.tmp", bootDevice ); + //make sure there is a folder for this to be saved in + struct stat st; + snprintf( filepath, sizeof( filepath ), "%s/wad/", bootDevice ); + if ( stat( filepath, &st ) != 0 ) + { + if ( subfoldercreate( filepath ) != 1 ) + { + WindowPrompt( tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ) ); + } + } + snprintf( filepath, sizeof( filepath ), "%s/wad/tmp.tmp", bootDevice ); - if ( infilesize < MB_SIZE ) - snprintf( filesizetxt, sizeof( filesizetxt ), tr( "Incoming file %0.2fKB" ), infilesize / KB_SIZE ); - else - snprintf( filesizetxt, sizeof( filesizetxt ), tr( "Incoming file %0.2fMB" ), infilesize / MB_SIZE ); + if ( infilesize < MB_SIZE ) + snprintf( filesizetxt, sizeof( filesizetxt ), tr( "Incoming file %0.2fKB" ), infilesize / KB_SIZE ); + else + snprintf( filesizetxt, sizeof( filesizetxt ), tr( "Incoming file %0.2fMB" ), infilesize / MB_SIZE ); - snprintf( temp, sizeof( temp ), tr( "Load file from: %s ?" ), GetIncommingIP() ); + snprintf( temp, sizeof( temp ), tr( "Load file from: %s ?" ), GetIncommingIP() ); - int choice = WindowPrompt( filesizetxt, temp, tr( "OK" ), tr( "Cancel" ) ); - gprintf( "\nchoice:%d", choice ); + int choice = WindowPrompt( filesizetxt, temp, tr( "OK" ), tr( "Cancel" ) ); + gprintf( "\nchoice:%d", choice ); - if ( choice == 1 ) - { + if ( choice == 1 ) + { - u32 read = 0; - u8 *temp = NULL; - int len = NETWORKBLOCKSIZE; - temp = ( u8 * ) malloc( infilesize ); + u32 read = 0; + u8 *temp = NULL; + int len = NETWORKBLOCKSIZE; + temp = ( u8 * ) malloc( infilesize ); - bool error = false; - u8 *ptr = temp; - gprintf( "\nrecieving shit" ); - while ( read < infilesize ) - { + bool error = false; + u8 *ptr = temp; + gprintf( "\nrecieving shit" ); + while ( read < infilesize ) + { - ShowProgress( tr( "Receiving file from:" ), GetIncommingIP(), NULL, read, infilesize, true ); + ShowProgress( tr( "Receiving file from:" ), GetIncommingIP(), NULL, read, infilesize, true ); - if ( infilesize - read < ( u32 ) len ) - len = infilesize - read; - else - len = NETWORKBLOCKSIZE; + if ( infilesize - read < ( u32 ) len ) + len = infilesize - read; + else + len = NETWORKBLOCKSIZE; - int result = network_read( ptr, len ); + int result = network_read( ptr, len ); - if ( result < 0 ) - { - WindowPrompt( tr( "Error while transfering data." ), 0, tr( "OK" ) ); - error = true; - break; - } - if ( !result ) - { - gprintf( "\n!RESULT" ); - break; - } - ptr += result; - read += result; - } - ProgressStop(); + if ( result < 0 ) + { + WindowPrompt( tr( "Error while transfering data." ), 0, tr( "OK" ) ); + error = true; + break; + } + if ( !result ) + { + gprintf( "\n!RESULT" ); + break; + } + ptr += result; + read += result; + } + ProgressStop(); - char filename[101]; - char tmptxt[200]; + char filename[101]; + char tmptxt[200]; - //bool installWad=0; - if ( !error ) - { - gprintf( "\nno error yet" ); + //bool installWad=0; + if ( !error ) + { + gprintf( "\nno error yet" ); - network_read( ( u8* ) &filename, 100 ); - gprintf( "\nfilename: %s", filename ); + network_read( ( u8* ) &filename, 100 ); + gprintf( "\nfilename: %s", filename ); - // Do we need to unzip this thing? - if ( wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4 ) - { - gprintf( "\nusing newer wiiload version" ); + // Do we need to unzip this thing? + if ( wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4 ) + { + gprintf( "\nusing newer wiiload version" ); - if ( uncfilesize != 0 ) // if uncfilesize == 0, it's not compressed - { - gprintf( "\ntrying to uncompress" ); - // It's compressed, uncompress - u8 *unc = ( u8 * ) malloc( uncfilesize ); - uLongf f = uncfilesize; - error = uncompress( unc, &f, temp, infilesize ) != Z_OK; - uncfilesize = f; + if ( uncfilesize != 0 ) // if uncfilesize == 0, it's not compressed + { + gprintf( "\ntrying to uncompress" ); + // It's compressed, uncompress + u8 *unc = ( u8 * ) malloc( uncfilesize ); + uLongf f = uncfilesize; + error = uncompress( unc, &f, temp, infilesize ) != Z_OK; + uncfilesize = f; - free( temp ); - temp = unc; - } - } + free( temp ); + temp = unc; + } + } - if ( !error ) - { - sprintf( tmptxt, "%s", filename ); - //if we got a wad - if ( strcasestr( tmptxt, ".wad" ) ) - { - FILE *file = fopen( filepath, "wb" ); - fwrite( temp, 1, ( uncfilesize > 0 ? uncfilesize : infilesize ), file ); - fclose( file ); + if ( !error ) + { + sprintf( tmptxt, "%s", filename ); + //if we got a wad + if ( strcasestr( tmptxt, ".wad" ) ) + { + FILE *file = fopen( filepath, "wb" ); + fwrite( temp, 1, ( uncfilesize > 0 ? uncfilesize : infilesize ), file ); + fclose( file ); - sprintf( tmptxt, "%s/wad/%s", bootDevice, filename ); - if ( checkfile( tmptxt ) )remove( tmptxt ); - rename( filepath, tmptxt ); + sprintf( tmptxt, "%s/wad/%s", bootDevice, filename ); + if ( checkfile( tmptxt ) )remove( tmptxt ); + rename( filepath, tmptxt ); - //check and make sure the wad we just saved is the correct size - u32 lSize; - file = fopen( tmptxt, "rb" ); + //check and make sure the wad we just saved is the correct size + u32 lSize; + file = fopen( tmptxt, "rb" ); - // obtain file size: - fseek ( file , 0 , SEEK_END ); - lSize = ftell ( file ); + // obtain file size: + fseek ( file , 0 , SEEK_END ); + lSize = ftell ( file ); - rewind ( file ); - if ( lSize == ( uncfilesize > 0 ? uncfilesize : infilesize ) ) - { - gprintf( "\nsize is ok" ); - int pick = WindowPrompt( tr( " Wad Saved as:" ), tmptxt, tr( "Install" ), tr( "Uninstall" ), tr( "Cancel" ) ); - //install or uninstall it - if ( pick == 1 ) - { - HaltGui(); - w.Remove( &titleTxt ); - w.Remove( &cancelBtn ); - w.Remove( &wifiBtn ); - w.Remove( &optionBrowser3 ); - ResumeGui(); + rewind ( file ); + if ( lSize == ( uncfilesize > 0 ? uncfilesize : infilesize ) ) + { + gprintf( "\nsize is ok" ); + int pick = WindowPrompt( tr( " Wad Saved as:" ), tmptxt, tr( "Install" ), tr( "Uninstall" ), tr( "Cancel" ) ); + //install or uninstall it + if ( pick == 1 ) + { + HaltGui(); + w.Remove( &titleTxt ); + w.Remove( &cancelBtn ); + w.Remove( &wifiBtn ); + w.Remove( &optionBrowser3 ); + ResumeGui(); - Wad_Install( file ); + Wad_Install( file ); - HaltGui(); - w.Append( &titleTxt ); - w.Append( &cancelBtn ); - w.Append( &wifiBtn ); - w.Append( &optionBrowser3 ); - ResumeGui(); + HaltGui(); + w.Append( &titleTxt ); + w.Append( &cancelBtn ); + w.Append( &wifiBtn ); + w.Append( &optionBrowser3 ); + ResumeGui(); - } - if ( pick == 2 )Wad_Uninstall( file ); - } - else gprintf( "\nBad size" ); - //close that beast, we're done with it - fclose ( file ); + } + if ( pick == 2 )Wad_Uninstall( file ); + } + else gprintf( "\nBad size" ); + //close that beast, we're done with it + fclose ( file ); - //do we want to keep the file in the wad folder - if ( WindowPrompt( tr( "Delete ?" ), tmptxt, tr( "Delete" ), tr( "Keep" ) ) != 0 ) - remove( tmptxt ); - } - else - { - WindowPrompt( tr( "ERROR:" ), tr( "Not a WAD file." ), tr( "OK" ) ); - } - } - } + //do we want to keep the file in the wad folder + if ( WindowPrompt( tr( "Delete ?" ), tmptxt, tr( "Delete" ), tr( "Keep" ) ) != 0 ) + remove( tmptxt ); + } + else + { + WindowPrompt( tr( "ERROR:" ), tr( "Not a WAD file." ), tr( "OK" ) ); + } + } + } - if ( error || read != infilesize ) - { - WindowPrompt( tr( "Error:" ), tr( "No data could be read." ), tr( "OK" ) ); + if ( error || read != infilesize ) + { + WindowPrompt( tr( "Error:" ), tr( "No data could be read." ), tr( "OK" ) ); - } - if ( temp )free( temp ); - } + } + if ( temp )free( temp ); + } - CloseConnection(); - ResumeNetworkWait(); - } + CloseConnection(); + ResumeNetworkWait(); + } #endif - if ( cancelBtn.GetState() == STATE_CLICKED ) - { - //break the loop and end the function - exit = true; - ret = -10; - } - else if ( screenShotBtn.GetState() == STATE_CLICKED ) - { - gprintf( "\n\tscreenShotBtn clicked" ); - screenShotBtn.ResetState(); - ScreenShot(); - gprintf( "...It's easy, mmmmmmKay" ); - } + if ( cancelBtn.GetState() == STATE_CLICKED ) + { + //break the loop and end the function + exit = true; + ret = -10; + } + else if ( screenShotBtn.GetState() == STATE_CLICKED ) + { + screenShotBtn.ResetState(); + ScreenShot(); + } } CloseConnection(); if ( IsNetworkInit() ) - HaltNetworkThread(); + HaltNetworkThread(); HaltGui(); mainWindow->Remove( &w ); diff --git a/source/prompts/TitleBrowser.h b/source/prompts/TitleBrowser.h index aa7a7ea7..c440ef91 100644 --- a/source/prompts/TitleBrowser.h +++ b/source/prompts/TitleBrowser.h @@ -9,5 +9,6 @@ #define _TITLEBROWSER_H_ int TitleBrowser(); +bool TitleSelector( char output[] ); #endif diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index e541f30c..7791b5f4 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -21,6 +21,7 @@ #include "usbloader/utils.h" #include "xml/xml.h" #include "wad/nandtitle.h" +#include "prompts/TitleBrowser.h" #define MAXOPTIONS 13 @@ -1074,15 +1075,38 @@ int MenuSettings() options2.SetValue( Idx, "%s", tr( opts_partitions[Settings.partitions_to_install] ) ); } - if ( ret == ++Idx || firstRun ) - { - if ( firstRun ) options2.SetName( Idx, "%s", tr( "Install 1:1 Copy" ) ); - if ( ret == Idx ) - { - Settings.fullcopy = Settings.fullcopy == 0 ? 1 : 0; - } - options2.SetValue( Idx, "%s", tr( opts_no_yes[Settings.fullcopy] ) ); - } + if ( ret == ++Idx || firstRun ) + { + if ( firstRun ) options2.SetName( Idx, "%s", tr( "Install 1:1 Copy" ) ); + if ( ret == Idx ) + { + Settings.fullcopy = Settings.fullcopy == 0 ? 1 : 0; + } + options2.SetValue( Idx, "%s", tr( opts_no_yes[Settings.fullcopy] ) ); + } + + if ( ret == ++Idx || firstRun ) + { + char* name = NULL; + if ( firstRun ) options2.SetName( Idx, "%s", tr( "Return To" ) ); + if ( ret == Idx ) + { + char tidChar[ 10 ]; + bool getChannel = TitleSelector( tidChar ); + if( getChannel ) + { + snprintf( Settings.returnTo, sizeof( Settings.returnTo ), "%s", tidChar ); + } + } + int haveTitle = titles.FindU32( Settings.returnTo ); + if( haveTitle >= 0 ) + { + name = titles.NameFromIndex( haveTitle ); + if( !strlen( name ) ) + name = NULL; + } + options2.SetValue( Idx, "%s", name ? name : tr( opts_off_on[ 0 ] ) ); + } firstRun = false; } @@ -2465,8 +2489,9 @@ int GameSettings( struct discHdr * header ) countrystrings = game_cfg->patchcountrystrings; alternatedol = game_cfg->loadalternatedol; alternatedoloffset = game_cfg->alternatedolstart; - reloadblock = game_cfg->iosreloadblock; - strlcpy( alternatedname, game_cfg->alternatedolname, sizeof( alternatedname ) ); + reloadblock = game_cfg->iosreloadblock; + strlcpy( alternatedname, game_cfg->alternatedolname, sizeof( alternatedname ) ); + returnToLoaderGV = game_cfg->returnTo; } else { @@ -2488,7 +2513,8 @@ int GameSettings( struct discHdr * header ) alternatedol = off; alternatedoloffset = 0; reloadblock = off; - strcpy( alternatedname, "" ); + strcpy( alternatedname, "" ); + returnToLoaderGV = 1; } ResumeGui(); @@ -2520,8 +2546,7 @@ int GameSettings( struct discHdr * header ) w.Remove( &MainButton3 ); w.Remove( &MainButton4 ); exit = false; - options2.SetLength( 0 ); -// optionBrowser2.SetScrollbar(1); + options2.SetLength( 0 ); w.Append( &optionBrowser2 ); optionBrowser2.SetClickable( true ); ResumeGui(); @@ -2659,15 +2684,32 @@ int GameSettings( struct discHdr * header ) options2.SetValue( Idx, "%s", tr( opts_parentalcontrol[parentalcontrolChoice] ) ); } - if ( ret == ++Idx || firstRun ) - { - if ( firstRun ) options2.SetName( Idx, "%s", tr( "Error 002 fix" ) ); - if ( ret == Idx && ++fix002 >= settings_error002_max ) - fix002 = 0; - options2.SetValue( Idx, "%s", tr( opts_error002[fix002] ) ); - } + if ( ret == ++Idx || firstRun ) + { + if ( firstRun ) options2.SetName( Idx, "%s", tr( "Error 002 fix" ) ); + if ( ret == Idx && ++fix002 >= settings_error002_max ) + fix002 = 0; + options2.SetValue( Idx, "%s", tr( opts_error002[fix002] ) ); + } - if ( ret == ++Idx || firstRun ) + if ( ret == ++Idx || firstRun ) + { + if ( firstRun ) options2.SetName( Idx, "%s", tr( "Return To" ) ); + if ( ret == Idx && ++returnToLoaderGV >= settings_off_on_max ) + returnToLoaderGV = 0; + + char text[ IMET_MAX_NAME_LEN ]; + int channel = titles.FindU32( Settings.returnTo );//is the channel set in the global settings actually installed? + + if( !returnToLoaderGV || channel < 0 )//channel is not installed or the uer wants to not use it + sprintf( text, "%s", tr( opts_off_on[ 0 ] ) ); + + else snprintf( text, sizeof( text ), "%s", titles.NameFromIndex( channel ) ); + + options2.SetValue( Idx, "%s", text ); + } + + if ( ret == ++Idx || firstRun ) { if ( firstRun ) options2.SetName( Idx, "%s", tr( "Patch Country Strings" ) ); if ( ret == Idx && ++countrystrings >= settings_off_on_max ) @@ -3002,8 +3044,9 @@ int GameSettings( struct discHdr * header ) iosChoice = i223; else iosChoice = i249; - parentalcontrolChoice = 0; - strcpy( alternatedname, "" ); + parentalcontrolChoice = 0; + strcpy( alternatedname, "" ); + returnToLoaderGV = 1; CFG_forget_game_opt( header->id ); /* commented because the database language now depends on the main language setting, this could be enabled again if there is a separate language setting for the database // if default language is different than language from main settings, reload titles diff --git a/source/settings/cfg.c b/source/settings/cfg.c index 1bd8da54..4aed72c6 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -41,6 +41,7 @@ u16 playcount = 0; u8 listDisplay = 0; u8 partition = -1; char alternatedname[40]; +u8 returnToLoaderGV = 1; //global variable used for returnToLoaderShit. defaults to "yes, patch return to loader" struct ID_Title { @@ -365,6 +366,7 @@ void Global_Default( void ) Settings.tooltips = TooltipsOn; char * empty = ""; snprintf( Settings.unlockCode, sizeof( Settings.unlockCode ), empty ); + snprintf( Settings.returnTo, sizeof( Settings.returnTo ), empty ); // Settings.godmode = 1; Settings.gamesound = 1; Settings.parentalcontrol = 0; @@ -747,48 +749,48 @@ void theme_set( char *name, char *val ) CFG_COORDS4( gamelist ) else CFG_COORDS4( gamegrid ) - else CFG_COORDS4( gamecarousel ) + else CFG_COORDS4( gamecarousel ) - else CFG_COORDS2( covers ) + else CFG_COORDS2( covers ) - else CFG_BOOL( show_id ) - else CFG_COORDS2( id ) + else CFG_BOOL( show_id ) + else CFG_COORDS2( id ) - else CFG_BOOL( show_region ) - else CFG_COORDS2( region ) + else CFG_BOOL( show_region ) + else CFG_COORDS2( region ) - else CFG_COORDS2( sdcard ) - else CFG_COORDS2( homebrew ) - else CFG_COORDS2( power ) - else CFG_COORDS2( home ) - else CFG_COORDS2( setting ) - else CFG_COORDS2( install ) + else CFG_COORDS2( sdcard ) + else CFG_COORDS2( homebrew ) + else CFG_COORDS2( power ) + else CFG_COORDS2( home ) + else CFG_COORDS2( setting ) + else CFG_COORDS2( install ) - else CFG_COORDS2( clock ) - else CFG_ALIGN( clock ) - else CFG_COLOR( clock ) + else CFG_COORDS2( clock ) + else CFG_ALIGN( clock ) + else CFG_COLOR( clock ) - else CFG_COLOR( info ) - else CFG_BOOL( show_hddinfo ) - else CFG_ALIGN( hddinfo ) - else CFG_COORDS2( hddinfo ) + else CFG_COLOR( info ) + else CFG_BOOL( show_hddinfo ) + else CFG_ALIGN( hddinfo ) + else CFG_COORDS2( hddinfo ) - else CFG_BOOL( show_gamecount ) - else CFG_ALIGN( gamecount ) - else CFG_COORDS2( gamecount ) + else CFG_BOOL( show_gamecount ) + else CFG_ALIGN( gamecount ) + else CFG_COORDS2( gamecount ) - else CFG_BOOL( show_tooltip ) - else CFG_VAL( tooltipAlpha ) + else CFG_BOOL( show_tooltip ) + else CFG_VAL( tooltipAlpha ) - else CFG_COLOR( prompttext ) - else CFG_COLOR( settingstext ) - else CFG_COLOR( gametext ) + else CFG_COLOR( prompttext ) + else CFG_COLOR( settingstext ) + else CFG_COLOR( gametext ) - else CFG_VAL( pagesize ) + else CFG_VAL( pagesize ) - else CFG_COORDS2( gamelist_favorite ) - else CFG_COORDS2( gamegrid_favorite ) - else CFG_COORDS2( gamecarousel_favorite ) + else CFG_COORDS2( gamelist_favorite ) + else CFG_COORDS2( gamegrid_favorite ) + else CFG_COORDS2( gamecarousel_favorite ) else CFG_COORDS2( gamelist_search ) else CFG_COORDS2( gamegrid_search ) @@ -1129,8 +1131,13 @@ void global_cfg_set( char *name, char *val ) } else if ( strcmp( name, "password" ) == 0 ) { - strlcpy( Settings.unlockCode, val, sizeof( Settings.unlockCode ) ); - return; + strlcpy( Settings.unlockCode, val, sizeof( Settings.unlockCode ) ); + return; + } + else if ( strcmp( name, "returnTo" ) == 0 ) + { + strlcpy( Settings.returnTo, val, sizeof( Settings.returnTo ) ); + return; } else if ( strcmp( name, "parentalcontrol" ) == 0 ) { @@ -1492,6 +1499,7 @@ void cfg_set_game_opt( struct Game_CFG *game, u8 *id ) } game->alternatedolstart = alternatedoloffset; strlcpy( game->alternatedolname, alternatedname, sizeof( game->alternatedolname ) ); + game->returnTo = returnToLoaderGV; } struct Game_NUM* cfg_get_game_num( u8 *id ) @@ -1602,6 +1610,7 @@ bool cfg_save_global() // save global settings fprintf( f, "partitions = %d\n ", Settings.partitions_to_install ); fprintf( f, "fullcopy = %d\n ", Settings.fullcopy ); fprintf( f, "beta_upgrades = %d\n ", Settings.beta_upgrades ); + fprintf( f, "returnTo = %s\n ", Settings.returnTo ); fclose( f ); return true; } @@ -1711,10 +1720,14 @@ void game_set( char *name, char *val ) game->alternatedolstart = opt_c; } } - if ( strcmp( "alternatedolname", opt_name ) == 0 ) - { - strlcpy( game->alternatedolname, opt_val, sizeof( game->alternatedolname ) ); - } + if ( strcmp( "alternatedolname", opt_name ) == 0 ) + { + strlcpy( game->alternatedolname, opt_val, sizeof( game->alternatedolname ) ); + } + if ( strcmp( "returnTo", opt_name ) == 0 ) + { + strlcpy( game->returnTo, opt_val, sizeof( game->returnTo ) ); + } } // next opt if ( np ) p = np + 1; @@ -1879,7 +1892,8 @@ bool cfg_save_games() fprintf( f, "patchcountrystrings:%d; ", cfg_game[i].patchcountrystrings ); fprintf( f, "loadalternatedol:%d;", cfg_game[i].loadalternatedol ); fprintf( f, "alternatedolstart:%d;", cfg_game[i].alternatedolstart ); - fprintf( f, "alternatedolname:%s;\n", cfg_game[i].alternatedolname ); + fprintf( f, "alternatedolname:%s;\n", cfg_game[i].alternatedolname ); + fprintf( f, "returnTo:%s;\n", cfg_game[i].returnTo ); } fprintf( f, "# END\n" ); fclose( f ); @@ -1956,6 +1970,7 @@ bool CFG_reset_all_playcounters() return true; } +#if 0 bool cfg_load_global() { char GXGlobal_cfg[26]; @@ -1989,7 +2004,7 @@ bool cfg_load_global() Settings.db_JPtoEN = 0; return cfg_parsefile( GXGlobal_cfg, &global_cfg_set ); } - +#endif struct Game_CFG* CFG_get_game_opt( const u8 *id ) diff --git a/source/settings/cfg.h b/source/settings/cfg.h index ea8f81c7..1ac780e0 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -214,6 +214,7 @@ extern "C" extern u16 playcount; extern u8 favoritevar; extern char alternatedname[40]; + extern u8 returnToLoaderGV; struct Game_CFG @@ -231,6 +232,7 @@ extern "C" u32 alternatedolstart; u8 patchcountrystrings; char alternatedolname[40]; + u8 returnTo; }; struct Game_NUM { @@ -462,6 +464,7 @@ extern "C" u8 fullcopy; u8 beta_upgrades; struct SParental parental; + char returnTo[ 20 ]; }; extern struct SSettings Settings; diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index 27bdd84c..a06626c1 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -59,7 +59,7 @@ void gamepatches( void * dst, int len, u8 videoSelected, u8 patchcountrystring, Anti_002_fix( dst, len ); } -s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset ) +s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo ) { app_entry appldr_entry; app_init appldr_init; @@ -102,6 +102,9 @@ s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u *( u32 * )0x80003188 = *( u32 * )0x80003140; } + u32 dolStart = 0x90000000; + u32 dolEnd = 0x0; + for ( ;; ) { void *dst = NULL; @@ -117,6 +120,18 @@ s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u gamepatches( dst, len, videoSelected, patchcountrystring, vipatch, cheat ); DCFlushRange( dst, len ); + + if( (u32)dst < dolStart )dolStart = (u32)dst; + if( (u32)dst + len > dolEnd ) dolEnd = (u32)dst + len; + } + + //this patch should be run on the entire dol at 1 time + if( !alternatedol && returnTo) + { + if( PatchReturnTo( (u32*)dolStart, dolEnd - dolStart , returnTo) ) + { + DCFlushRange( (u32*)dolStart, dolEnd - dolStart ); + } } *entry = appldr_final(); diff --git a/source/usbloader/apploader.h b/source/usbloader/apploader.h index 126f4378..b8d266d1 100644 --- a/source/usbloader/apploader.h +++ b/source/usbloader/apploader.h @@ -7,11 +7,11 @@ extern "C" #endif /* Entry point */ - typedef void ( *entry_point )( void ); +typedef void ( *entry_point )( void ); /* Prototypes */ - s32 Apploader_Run( entry_point *, u8, u8, u8, u8, u8, u8, u32 ); - void gamepatches( void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat ); +s32 Apploader_Run( entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo ); +void gamepatches( void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat ); #ifdef __cplusplus } diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index b7b82d1c..c44bcdc9 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -296,7 +296,7 @@ s32 Disc_IsWii( void ) return 0; } -s32 Disc_BootPartition( u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset ) +s32 Disc_BootPartition( u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo ) { entry_point p_entry; @@ -320,7 +320,7 @@ s32 Disc_BootPartition( u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 p PoPPatch(); /* Run apploader */ - ret = Apploader_Run( &p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset ); + ret = Apploader_Run( &p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset, returnTo ); if ( ret < 0 ) return ret; @@ -397,7 +397,7 @@ s32 Disc_BootPartition( u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 p return 0; } -s32 Disc_WiiBoot( u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset ) +s32 Disc_WiiBoot( u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol, u32 alternatedoloffset, u32 returnTo ) { u64 offset; s32 ret; @@ -408,7 +408,7 @@ s32 Disc_WiiBoot( u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, return ret; /* Boot partition */ - return Disc_BootPartition( offset, videoselected, cheat, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset ); + return Disc_BootPartition( offset, videoselected, cheat, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset, returnTo ); } diff --git a/source/usbloader/disc.h b/source/usbloader/disc.h index 4a10608d..1adfcc32 100644 --- a/source/usbloader/disc.h +++ b/source/usbloader/disc.h @@ -50,8 +50,8 @@ extern "C" s32 Disc_SetUSB( const u8 * ); s32 Disc_ReadHeader( void * ); s32 Disc_IsWii( void ); - s32 Disc_BootPartition( u64, u8, u8, u8, u8, u8, u8, u32 ); - s32 Disc_WiiBoot( u8, u8, u8, u8, u8, u8, u32 ); + s32 Disc_BootPartition( u64, u8, u8, u8, u8, u8, u8, u32, u32 returnTo ); + s32 Disc_WiiBoot( u8, u8, u8, u8, u8, u8, u32, u32 returnTo ); s32 __Disc_FindPartition( u64 *outbuf ); void PatchCountryStrings( void *Address, int Size ); s32 __Disc_FindPartition( u64 *outbuf ); diff --git a/source/wad/nandtitle.cpp b/source/wad/nandtitle.cpp index 59aab496..664db7d4 100644 --- a/source/wad/nandtitle.cpp +++ b/source/wad/nandtitle.cpp @@ -8,6 +8,23 @@ extern "C" static u8 tmd_buf[ MAX_SIGNED_TMD_SIZE ] ATTRIBUTE_ALIGN( 32 ); +//based on one from comex's nand formatter +static u64 atoi_hex( const char *s ) { + u64 ret=0; + u32 n = strlen( s ); + + for( u32 i = 0; i < n; i++) { + if(s[i] > 0x39) { + ret += (s[i] & ~0x20) - 0x37; + } else { + ret += (s[i]-0x30); + } + if (i != (n-1)) ret *= 16; + } + + return ret; +} + NandTitle::NandTitle() { numTitles = 0; @@ -444,3 +461,20 @@ err: return ret; } + +int NandTitle::FindU64( const char *s ) +{ + u64 tid = atoi_hex( s ); + return IndexOf( tid ); +} + +int NandTitle::FindU32( const char *s ) +{ + u64 tid = atoi_hex( s ); + for ( u32 i = 0; i < numTitles; i++ ) + { + if ( TITLE_LOWER( list[ i ] ) == TITLE_LOWER( tid ) ) + return i; + } + return WII_EINSTALL; +} diff --git a/source/wad/nandtitle.h b/source/wad/nandtitle.h index 231e7137..8b327e9b 100644 --- a/source/wad/nandtitle.h +++ b/source/wad/nandtitle.h @@ -86,6 +86,9 @@ class NandTitle bool Exists( u64 tid ); bool ExistsFromIndex( u32 i ); + int FindU64( const char *s ); + int FindU32( const char *s ); + s32 GetTicketViews( u64 tid, tikview **outbuf, u32 *outlen ); u64 operator[]( u32 i ) { return At( i ); }