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