From 22ca798b5e5780907c9f27d37cb736014e0d786c Mon Sep 17 00:00:00 2001 From: dimok321 <15055714+dimok789@users.noreply.github.com> Date: Tue, 16 Jun 2009 11:29:07 +0000 Subject: [PATCH] *Added Alternate DOL support which is used to boot games that don't work due to IOS Reloads like Mortal Kombat NOTE: There is a GameSettings you need to turn ON to load Alternate DOLs. The alternate DOL has to be called 6 IDs .dol for example RHDP8P.dol and has to be in the root of the SD. Giantpune will add custom path support i dont have time for it. --- gui.pnproj | 2 +- source/language/language.c | 5 ++ source/language/language.h | 1 + source/menu.cpp | 4 +- source/settings/Settings.cpp | 16 +++- source/settings/cfg.c | 9 ++- source/settings/cfg.h | 2 + source/usbloader/alternatedol.c | 126 ++++++++++++++++++++++++++++++ source/usbloader/alternatedol.h | 19 +++++ source/usbloader/apploader.c | 131 +++++++++++++++++++------------- source/usbloader/apploader.h | 13 +++- source/usbloader/disc.c | 9 ++- source/usbloader/disc.h | 4 +- 13 files changed, 273 insertions(+), 68 deletions(-) create mode 100644 source/usbloader/alternatedol.c create mode 100644 source/usbloader/alternatedol.h diff --git a/gui.pnproj b/gui.pnproj index f62d3f22..a5e741a0 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/language/language.c b/source/language/language.c index 7df1159b..e195ac74 100644 --- a/source/language/language.c +++ b/source/language/language.c @@ -36,6 +36,7 @@ snprintf(LANGUAGE.ok, sizeof(LANGUAGE.ok), "OK"); snprintf(LANGUAGE.addToFavorite, sizeof(LANGUAGE.addToFavorite), "Favorite"); snprintf(LANGUAGE.all, sizeof(LANGUAGE.all), "Alphabetical"); snprintf(LANGUAGE.AppLanguage, sizeof(LANGUAGE.AppLanguage), "App Language"); +snprintf(LANGUAGE.Alternatedol, sizeof(LANGUAGE.Alternatedol), "Alternate DOL"); snprintf(LANGUAGE.t3Covers, sizeof(LANGUAGE.t3Covers), "3D Covers"); snprintf(LANGUAGE.Areyousure, sizeof(LANGUAGE.Areyousure), "Are you sure?"); snprintf(LANGUAGE.available, sizeof(LANGUAGE.available), "available"); @@ -322,6 +323,10 @@ void language_set(char *name, char *val) strcopy(LANGUAGE.AppLanguage, val, sizeof(LANGUAGE.AppLanguage)); return; } + if (strcmp(name, "Alternatedol") == 0) { + strcopy(LANGUAGE.Alternatedol, val, sizeof(LANGUAGE.Alternatedol)); + return; + } if (strcmp(name, "Areyousure") == 0) { strcopy(LANGUAGE.Areyousure, val, sizeof(LANGUAGE.Areyousure)); return; diff --git a/source/language/language.h b/source/language/language.h index df51d486..17cbb6e2 100644 --- a/source/language/language.h +++ b/source/language/language.h @@ -37,6 +37,7 @@ struct LANGUAGE char Areyousure[50]; char AutoPatch[30]; char Adultsonly[50]; + char Alternatedol[50]; char awesometool[50]; char Back[20]; char Backgroundmusic[80]; diff --git a/source/menu.cpp b/source/menu.cpp index e11894bf..be6301fb 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -1837,6 +1837,7 @@ int MainMenu(int menu) onlinefix = game_cfg->onlinegame; iosChoice = game_cfg->ios; countrystrings = game_cfg->patchcountrystrings; + alternatedol = game_cfg->loadalternatedol; } else { videoChoice = Settings.video; languageChoice = Settings.language; @@ -1850,6 +1851,7 @@ int MainMenu(int menu) fix002 = Settings.error002; onlinefix = off; countrystrings = Settings.patchcountrystrings; + alternatedol = off; } int ios2; switch(iosChoice) { @@ -2011,7 +2013,7 @@ int MainMenu(int menu) break; } - ret = Disc_WiiBoot(videoselected, cheat, vipatch, countrystrings, errorfixer002); + ret = Disc_WiiBoot(videoselected, cheat, vipatch, countrystrings, errorfixer002, alternatedol); if (ret < 0) { Sys_LoadMenu(); } diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index cdc07f71..4a165e3d 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -1681,7 +1681,7 @@ int GameSettings(struct discHdr * header) strncat(gameName, "...", 3); } - customOptionList options3(10); + customOptionList options3(11); options3.SetName(0,"%s", LANGUAGE.VideoMode); options3.SetName(1,"%s", LANGUAGE.VIDTVPatch); options3.SetName(2,"%s", LANGUAGE.Language); @@ -1691,7 +1691,8 @@ int GameSettings(struct discHdr * header) options3.SetName(6,"%s", LANGUAGE.Error002fix); options3.SetName(7,"%s", LANGUAGE.Onlinefix); options3.SetName(8,"%s", LANGUAGE.Patchcountrystrings); - options3.SetName(9,"%s", LANGUAGE.Defaultgamesettings); + options3.SetName(9,"%s", LANGUAGE.Alternatedol); + options3.SetName(10,"%s", LANGUAGE.Defaultgamesettings); 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); @@ -1780,6 +1781,7 @@ int GameSettings(struct discHdr * header) fix002 = game_cfg->errorfix002; onlinefix = game_cfg->onlinegame; countrystrings = game_cfg->patchcountrystrings; + alternatedol = game_cfg->loadalternatedol; } else { @@ -1796,6 +1798,7 @@ int GameSettings(struct discHdr * header) fix002 = Settings.error002; onlinefix = off; countrystrings = Settings.patchcountrystrings; + alternatedol = off; } int opt_lang = languageChoice; // backup language setting @@ -1850,7 +1853,10 @@ int GameSettings(struct discHdr * header) if (countrystrings == on) options3.SetValue(8,LANGUAGE.ON); else if (countrystrings == off) options3.SetValue(8,LANGUAGE.OFF); - options3.SetValue(9, NULL); + if (alternatedol == on) options3.SetValue(9,LANGUAGE.ON); + else if (alternatedol == off) options3.SetValue(9,LANGUAGE.OFF); + + options3.SetValue(10, NULL); if(shutdown == 1) Sys_Shutdown(); @@ -1889,6 +1895,9 @@ int GameSettings(struct discHdr * header) countrystrings = (countrystrings+1) % 2; break; case 9: + alternatedol = (alternatedol+1) % 2; + break; + case 10: int choice = WindowPrompt(LANGUAGE.Areyousure,0,LANGUAGE.Yes,LANGUAGE.Cancel,0,0); if(choice == 1) { videoChoice = Settings.video; @@ -1898,6 +1907,7 @@ int GameSettings(struct discHdr * header) fix002 = Settings.error002; onlinefix = off; countrystrings = Settings.patchcountrystrings; + alternatedol = off; if(Settings.cios == ios222) { iosChoice = i222; } else { diff --git a/source/settings/cfg.c b/source/settings/cfg.c index 8c20f8ab..ad6576ef 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -37,6 +37,7 @@ u8 iosChoice = 0; u8 parentalcontrolChoice = 0; u8 fix002 = 0; u8 countrystrings = 0; +u8 alternatedol = 0; u8 onlinefix = 0; u8 xflip = 0; u8 sort = 0; @@ -1128,6 +1129,7 @@ void cfg_set_game_opt(struct Game_CFG *game, u8 *id) game->parentalcontrol = parentalcontrolChoice; game->errorfix002 = fix002; game->patchcountrystrings = countrystrings; + game->loadalternatedol = alternatedol; game->onlinegame = onlinefix; } @@ -1290,12 +1292,16 @@ void game_set(char *name, char *val) game->patchcountrystrings = opt_c; } } + if (strcmp("loadalternatedol", opt_name) == 0) { + if (sscanf(opt_val, "%hd", &opt_c) == 1) { + game->loadalternatedol = opt_c; + } + } if (strcmp("onlinegame", opt_name) == 0) { if (sscanf(opt_val, "%hd", &opt_c) == 1) { game->onlinegame = opt_c; } } - } // next opt if (np) p = np + 1; else p = NULL; @@ -1442,6 +1448,7 @@ bool cfg_save_games() fprintf(f, "pctrl:%d; ", cfg_game[i].parentalcontrol); fprintf(f, "errorfix002:%d; ", cfg_game[i].errorfix002); fprintf(f, "patchcountrystrings:%d; ", cfg_game[i].patchcountrystrings); + fprintf(f, "loadalternatedol:%d; ", cfg_game[i].loadalternatedol); fprintf(f, "onlinegame:%d;\n", cfg_game[i].onlinegame); } fprintf(f, "# END\n"); diff --git a/source/settings/cfg.h b/source/settings/cfg.h index 39cf3558..342d2002 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -156,6 +156,7 @@ extern u8 faveChoice; extern u8 parentalcontrolChoice; extern u8 fix002; extern u8 countrystrings; +extern u8 alternatedol; extern u8 onlinefix; extern u8 xflip; extern u8 qboot; @@ -176,6 +177,7 @@ struct Game_CFG u8 ios; u8 parentalcontrol; u8 errorfix002; + u8 loadalternatedol; u8 patchcountrystrings; u8 onlinegame; }; diff --git a/source/usbloader/alternatedol.c b/source/usbloader/alternatedol.c new file mode 100644 index 00000000..db93eb46 --- /dev/null +++ b/source/usbloader/alternatedol.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include + +#include "fatmounter.h" + +/** Alternate dolloader made by WiiPower modified by dimok **/ + +bool Load_Dol(void **buffer, int* dollen, char * filepath) +{ + int ret; + FILE* file; + void* dol_buffer; + + char fullpath[200]; + char gameidbuffer6[7]; + memset(gameidbuffer6, 0, 7); + memcpy(gameidbuffer6, (char*)0x80000000, 6); + snprintf(fullpath, 200, "%s%s.dol", filepath, gameidbuffer6); + + SDCard_Init(); + USBDevice_Init(); + + file = fopen(fullpath, "rb"); + + if(file == NULL) + { + fclose(file); + SDCard_deInit(); + USBDevice_deInit(); + return false; + } + + int filesize; + fseek(file, 0, SEEK_END); + filesize = ftell(file); + fseek(file, 0, SEEK_SET); + + dol_buffer = malloc(filesize); + if (dol_buffer == NULL) + { + fclose(file); + SDCard_deInit(); + USBDevice_deInit(); + return false; + } + ret = fread( dol_buffer, 1, filesize, file); + if(ret != filesize) + { + free(dol_buffer); + fclose(file); + SDCard_deInit(); + USBDevice_deInit(); + return false; + } + fclose(file); + + SDCard_deInit(); + USBDevice_deInit(); + *buffer = dol_buffer; + *dollen = filesize; + return true; +} + +bool Remove_001_Protection(void *Address, int Size) +{ + u8 SearchPattern[16] = { 0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 }; + u8 PatchData[16] = { 0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 }; + + void *Addr = Address; + void *Addr_end = Address+Size; + + while(Addr <= Addr_end-sizeof(SearchPattern)) + { + if(memcmp(Addr, SearchPattern, sizeof(SearchPattern))==0) + { + memcpy(Addr,PatchData,sizeof(PatchData)); + return true; + } + Addr += 4; + } + return false; +} + +typedef struct _dolheader { + u32 text_pos[7]; + u32 data_pos[11]; + u32 text_start[7]; + u32 data_start[11]; + u32 text_size[7]; + u32 data_size[11]; + u32 bss_start; + u32 bss_size; + u32 entry_point; +} dolheader; + +u32 load_dol_image(void *dolstart) { + + u32 i; + dolheader *dolfile; + + if (dolstart) { + dolfile = (dolheader *) dolstart; + for (i = 0; i < 7; i++) { + if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue; + VIDEO_WaitVSync(); + ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]); + memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]); + } + + for(i = 0; i < 11; i++) { + if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue; + VIDEO_WaitVSync(); + memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]); + DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]); + } + /* + memset ((void *) dolfile->bss_start, 0, dolfile->bss_size); + DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size); + */ + return dolfile->entry_point; + } + return 0; +} diff --git a/source/usbloader/alternatedol.h b/source/usbloader/alternatedol.h new file mode 100644 index 00000000..42901e10 --- /dev/null +++ b/source/usbloader/alternatedol.h @@ -0,0 +1,19 @@ +#ifndef _ALTERNATEDOL_H_ +#define _ALTERNATEDOL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* not the full path is needed here, the path where the dol is */ + +bool Load_Dol(void **buffer, int* dollen, char * path); +bool Remove_001_Protection(void *Address, int Size); +u32 load_dol_image(void * dolstart); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index 5f3bd2e1..73dceaeb 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -8,6 +8,7 @@ #include "wdvd.h" #include "wpad.h" #include "disc.h" +#include "alternatedol.h" /*KENOBI! - FISHEARS*/ extern const unsigned char kenobiwii[]; @@ -216,9 +217,59 @@ bool Search_and_patch_Video_Modes(void *Address, u32 Size, GXRModeObj* Table[]) return found; +} + +void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch) +{ + GXRModeObj** table = NULL; + if (videoSelected == 5) // patch + + { + switch(CONF_GetVideo()) + { + case CONF_VIDEO_PAL: + if(CONF_GetEuRGB60() > 0) + { + table = NTSC2PAL60; + } + else + { + table = NTSC2PAL; + } + break; + + case CONF_VIDEO_MPAL: + + + + table = NTSC2PAL; + break; + + + default: + table = PAL2NTSC; + break; + } + Search_and_patch_Video_Modes(dst, len, table); + } + + /*GAME HOOK - FISHEARS*/ + dogamehooks(dst,len); + + if (vipatch) + vidolpatcher(dst,len); + + + /*LANGUAGE PATCH - FISHEARS*/ + langpatcher(dst,len); + + /*Thanks to WiiPower*/ + if(patchcountrystring == 1) + PatchCountryStrings(dst, len); + } -s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix) +s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol) { app_entry appldr_entry; app_init appldr_init; @@ -268,8 +319,7 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 for (;;) { void *dst = NULL; - int len = 0, offset = 0; - GXRModeObj** table = NULL; + int len = 0, offset = 0; /* Run apploader main function */ ret = appldr_main(&dst, &len, &offset); @@ -279,59 +329,32 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8 /* Read data from DVD */ WDVD_Read(dst, len, (u64)(offset << 2)); - - if (videoSelected == 5) // patch - - { - switch(CONF_GetVideo()) - { - case CONF_VIDEO_PAL: - if(CONF_GetEuRGB60() > 0) - { - table = NTSC2PAL60; - } - else - { - table = NTSC2PAL; - } - break; - - case CONF_VIDEO_MPAL: - - - - table = NTSC2PAL; - break; - - - default: - table = PAL2NTSC; - break; - } - Search_and_patch_Video_Modes(dst, len, table); - } - - /*GAME HOOK - FISHEARS*/ - dogamehooks(dst,len); - - if (vipatch) - vidolpatcher(dst,len); - - - /*LANGUAGE PATCH - FISHEARS*/ - langpatcher(dst,len); - - /*Thanks to WiiPower*/ - if(patchcountrystring == 1) - PatchCountryStrings(dst, len); + gamepatches(dst, len, videoSelected, patchcountrystring, vipatch); DCFlushRange(dst, len); - } - /* Set entry point from apploader */ - *entry = appldr_final(); + } + + *entry = appldr_final(); + + /** Load alternate dol if set **/ + if(alternatedol == 1) { + void *dolbuffer; + int dollen; + char * path = "SD:/"; + bool dolloaded = Load_Dol(&dolbuffer, &dollen, path); + if(dolloaded) { + Remove_001_Protection(dolbuffer, dollen); + + DCFlushRange(dolbuffer, dollen); + + gamepatches(dolbuffer, dollen, videoSelected, patchcountrystring, vipatch); + + DCFlushRange(dolbuffer, dollen); + + /* Set entry point from apploader */ + *entry = (entry_point) load_dol_image(dolbuffer); + } + } return 0; -} -#ifdef __cplusplus } -#endif diff --git a/source/usbloader/apploader.h b/source/usbloader/apploader.h index 6123ad71..7f658ee9 100644 --- a/source/usbloader/apploader.h +++ b/source/usbloader/apploader.h @@ -1,10 +1,19 @@ #ifndef _APPLOADER_H_ #define _APPLOADER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* Entry point */ typedef void (*entry_point)(void); /* Prototypes */ -s32 Apploader_Run(entry_point *, u8, u8, u8, u8, u8); +s32 Apploader_Run(entry_point *, u8, u8, u8, u8, u8, u8); -#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index 13813953..3deaa62d 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -10,6 +10,7 @@ #include "disc.h" #include "video.h" #include "wdvd.h" +#include "alternatedol.h" /* Constants */ #define PTABLE_OFFSET 0x40000 @@ -253,7 +254,7 @@ s32 Disc_IsWii(void) return 0; } -s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix) +s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol) { entry_point p_entry; @@ -265,7 +266,7 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa return ret; /* Run apploader */ - ret = Apploader_Run(&p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix); + ret = Apploader_Run(&p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix, alternatedol); if (ret < 0) return ret; @@ -300,7 +301,7 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa return 0; } -s32 Disc_WiiBoot(u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix) +s32 Disc_WiiBoot(u8 videoselected, u8 cheat, u8 vipatch, u8 patchcountrystring, u8 error002fix, u8 alternatedol) { u64 offset; s32 ret; @@ -311,7 +312,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); + return Disc_BootPartition(offset, videoselected, cheat, vipatch, patchcountrystring, error002fix, alternatedol); } void PatchCountryStrings(void *Address, int Size) diff --git a/source/usbloader/disc.h b/source/usbloader/disc.h index d78366ab..5c9d200c 100644 --- a/source/usbloader/disc.h +++ b/source/usbloader/disc.h @@ -46,8 +46,8 @@ void __Disc_SetLowMem(void); s32 Disc_SetUSB(u8 *); s32 Disc_ReadHeader(void *); s32 Disc_IsWii(void); -s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8); -s32 Disc_WiiBoot(u8, u8, u8, u8, u8); +s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8); +s32 Disc_WiiBoot(u8, u8, u8, u8, u8, u8); void PatchCountryStrings(void *Address, int Size); #ifdef __cplusplus