mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2025-01-11 11:29:09 +01:00
-changed quite alot of things in apploader (thanks to GX again,
before the NSMBW and Prince of Persia patch did nothing at all) -fixed typo in wip debug print (before it didnt work at all so nobody noticed)
This commit is contained in:
parent
8ca6d767bc
commit
7714c6e6d8
@ -11,6 +11,7 @@
|
||||
#include "wbfs.h"
|
||||
#include "sys.h"
|
||||
#include "gecko.h"
|
||||
#include "fst.h"
|
||||
|
||||
/* Apploader function pointers */
|
||||
typedef int (*app_main)(void **dst, int *size, int *offset);
|
||||
@ -26,16 +27,19 @@ static u8 *appldr = (u8 *) 0x81200000;
|
||||
|
||||
/* Variables */
|
||||
static u32 buffer[0x20] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
static bool maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
||||
static bool Remove_001_Protection(void *Address, int Size);
|
||||
static bool PrinceOfPersiaPatch();
|
||||
|
||||
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
||||
void PatchCountryStrings(void *Address, int Size);
|
||||
bool Remove_001_Protection(void *Address, int Size);
|
||||
bool PrinceOfPersiaPatch();
|
||||
bool NewSuperMarioBrosPatch();
|
||||
bool hookpatched = false;
|
||||
|
||||
s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
|
||||
{
|
||||
void *dst = NULL;
|
||||
int len = 0;
|
||||
int offset = 0;
|
||||
{
|
||||
void *dst = NULL;
|
||||
int len = 0;
|
||||
int offset = 0;
|
||||
u32 appldr_len;
|
||||
s32 ret;
|
||||
app_init appldr_init;
|
||||
@ -63,24 +67,22 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
|
||||
|
||||
/* Initialize apploader */
|
||||
appldr_init(gprintf);
|
||||
|
||||
bool hookpatched = false;
|
||||
|
||||
while (appldr_main(&dst, &len, &offset))
|
||||
{
|
||||
/* Read data from DVD */
|
||||
{
|
||||
/* Read data from DVD */
|
||||
WDVD_Read(dst, len, (u64)(offset << 2));
|
||||
if(maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio))
|
||||
hookpatched = true;
|
||||
}
|
||||
maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio);
|
||||
}
|
||||
|
||||
if (hooktype != 0 && !hookpatched)
|
||||
free_wip();
|
||||
if (hooktype != 0)
|
||||
{
|
||||
gprintf("Error: Could not patch the hook\n");
|
||||
gprintf("Ocarina and debugger won't work\n");
|
||||
if(hookpatched)
|
||||
ocarina_do_code();
|
||||
else
|
||||
gprintf("Error: Could not patch the hook, Ocarina and debugger won't work\n");
|
||||
}
|
||||
|
||||
PrinceOfPersiaPatch();
|
||||
|
||||
/* Set entry point from apploader */
|
||||
*entry = appldr_final();
|
||||
@ -93,6 +95,32 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
|
||||
{
|
||||
PrinceOfPersiaPatch();
|
||||
NewSuperMarioBrosPatch();
|
||||
|
||||
patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
|
||||
|
||||
if(hooktype != 0 && dogamehooks(dst, len, false))
|
||||
hookpatched = true;
|
||||
if(vipatch)
|
||||
vidolpatcher(dst, len);
|
||||
if(configbytes[0] != 0xCD)
|
||||
langpatcher(dst, len);
|
||||
if(countryString)
|
||||
PatchCountryStrings(dst, len); // Country Patch by WiiPower
|
||||
if(aspectRatio != -1)
|
||||
PatchAspectRatio(dst, len, aspectRatio);
|
||||
|
||||
Remove_001_Protection(dst, len);
|
||||
|
||||
do_wip_code((u8 *)dst, len);
|
||||
|
||||
DCFlushRange(dst, len);
|
||||
ICInvalidateRange(dst, len);
|
||||
}
|
||||
|
||||
void PatchCountryStrings(void *Address, int Size)
|
||||
{
|
||||
u8 SearchPattern[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
@ -168,98 +196,97 @@ void PatchCountryStrings(void *Address, int Size)
|
||||
}
|
||||
}
|
||||
|
||||
static bool PrinceOfPersiaPatch()
|
||||
bool PrinceOfPersiaPatch()
|
||||
{
|
||||
if (memcmp("SPX", (char *)0x80000000, 3) == 0 || memcmp("RPW", (char *)0x80000000, 3) == 0)
|
||||
if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0)
|
||||
return false;
|
||||
|
||||
WIP_Code * CodeList = MEM2_alloc(5 * sizeof(WIP_Code));
|
||||
CodeList[0].offset = 0x007AAC6A;
|
||||
CodeList[0].srcaddress = 0x7A6B6F6A;
|
||||
CodeList[0].dstaddress = 0x6F6A7A6B;
|
||||
CodeList[1].offset = 0x007AAC75;
|
||||
CodeList[1].srcaddress = 0x7C7A6939;
|
||||
CodeList[1].dstaddress = 0x69397C7A;
|
||||
CodeList[2].offset = 0x007AAC82;
|
||||
CodeList[2].srcaddress = 0x7376686B;
|
||||
CodeList[2].dstaddress = 0x686B7376;
|
||||
CodeList[3].offset = 0x007AAC92;
|
||||
CodeList[3].srcaddress = 0x80717570;
|
||||
CodeList[3].dstaddress = 0x75708071;
|
||||
CodeList[4].offset = 0x007AAC9D;
|
||||
CodeList[4].srcaddress = 0x82806F3F;
|
||||
CodeList[4].dstaddress = 0x6F3F8280;
|
||||
|
||||
if (set_wip_list(CodeList, 5) == false)
|
||||
{
|
||||
u8 *p = (u8 *)0x807AEB6A;
|
||||
*p++ = 0x6F;
|
||||
*p++ = 0x6A;
|
||||
*p++ = 0x7A;
|
||||
*p++ = 0x6B;
|
||||
p = (u8 *)0x807AEB75;
|
||||
*p++ = 0x69;
|
||||
*p++ = 0x39;
|
||||
*p++ = 0x7C;
|
||||
*p++ = 0x7A;
|
||||
p = (u8 *)0x807AEB82;
|
||||
*p++ = 0x68;
|
||||
*p++ = 0x6B;
|
||||
*p++ = 0x73;
|
||||
*p++ = 0x76;
|
||||
p = (u8 *)0x807AEB92;
|
||||
*p++ = 0x75;
|
||||
*p++ = 0x70;
|
||||
*p++ = 0x80;
|
||||
*p++ = 0x71;
|
||||
p = (u8 *)0x807AEB9D;
|
||||
*p++ = 0x6F;
|
||||
*p++ = 0x3F;
|
||||
*p++ = 0x82;
|
||||
*p++ = 0x80;
|
||||
return true;
|
||||
MEM2_free(CodeList);
|
||||
CodeList = NULL;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NewSuperMarioBrosPatch(void *Address, int Size)
|
||||
bool NewSuperMarioBrosPatch()
|
||||
{
|
||||
if (memcmp("SMN", (char *)0x80000000, 3) == 0)
|
||||
WIP_Code * CodeList = NULL;
|
||||
|
||||
if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0)
|
||||
{
|
||||
u8 SearchPattern1[32] = {// PAL
|
||||
0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6,
|
||||
0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30,
|
||||
0x48, 0x12, 0xD9, 0x39, 0x7C, 0x7B, 0x1B, 0x78,
|
||||
0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78};
|
||||
u8 SearchPattern2[32] = {// NTSC
|
||||
0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6,
|
||||
0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30,
|
||||
0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78,
|
||||
0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78};
|
||||
u8 PatchData[4] = {0x4E, 0x80, 0x00, 0x20};
|
||||
|
||||
void *Addr = Address;
|
||||
void *Addr_end = Address+Size;
|
||||
while (Addr <= Addr_end-sizeof(SearchPattern1))
|
||||
{
|
||||
if ( memcmp(Addr, SearchPattern1, sizeof(SearchPattern1))==0
|
||||
|| memcmp(Addr, SearchPattern2, sizeof(SearchPattern2))==0)
|
||||
{
|
||||
memcpy(Addr,PatchData,sizeof(PatchData));
|
||||
return true;
|
||||
}
|
||||
Addr += 4;
|
||||
}
|
||||
CodeList = MEM2_alloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB610;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
CodeList[1].offset = 0x001CED53;
|
||||
CodeList[1].srcaddress = 0xDA000000;
|
||||
CodeList[1].dstaddress = 0x71000000;
|
||||
CodeList[2].offset = 0x001CED6B;
|
||||
CodeList[2].srcaddress = 0xDA000000;
|
||||
CodeList[2].dstaddress = 0x71000000;
|
||||
}
|
||||
return false;
|
||||
else if (memcmp("SMNP01", (char *) 0x80000000, 6) == 0)
|
||||
{
|
||||
CodeList = MEM2_alloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB750;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
CodeList[1].offset = 0x001CEE90;
|
||||
CodeList[1].srcaddress = 0x38A000DA;
|
||||
CodeList[1].dstaddress = 0x38A00071;
|
||||
CodeList[2].offset = 0x001CEEA8;
|
||||
CodeList[2].srcaddress = 0x388000DA;
|
||||
CodeList[2].dstaddress = 0x38800071;
|
||||
}
|
||||
else if (memcmp("SMNJ01", (char *) 0x80000000, 6) == 0)
|
||||
{
|
||||
CodeList = MEM2_alloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB420;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
CodeList[1].offset = 0x001CEB63;
|
||||
CodeList[1].srcaddress = 0xDA000000;
|
||||
CodeList[1].dstaddress = 0x71000000;
|
||||
CodeList[2].offset = 0x001CEB7B;
|
||||
CodeList[2].srcaddress = 0xDA000000;
|
||||
CodeList[2].dstaddress = 0x71000000;
|
||||
}
|
||||
if (CodeList && set_wip_list(CodeList, 3) == false)
|
||||
{
|
||||
MEM2_free(CodeList);
|
||||
CodeList = NULL;
|
||||
return false;
|
||||
}
|
||||
return CodeList != NULL;
|
||||
}
|
||||
|
||||
static bool maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
DCFlushRange(dst, len);
|
||||
|
||||
patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
|
||||
|
||||
if (hooktype != 0) ret = dogamehooks(dst, len, false);
|
||||
if (vipatch) vidolpatcher(dst, len);
|
||||
if (configbytes[0] != 0xCD) langpatcher(dst, len);
|
||||
if (countryString) PatchCountryStrings(dst, len); // Country Patch by WiiPower
|
||||
if (aspectRatio != -1) PatchAspectRatio(dst, len, aspectRatio);
|
||||
Remove_001_Protection(dst, len);
|
||||
|
||||
// NSMB Patch by WiiPower
|
||||
NewSuperMarioBrosPatch(dst,len);
|
||||
|
||||
do_wip_code((u8 *) dst, len);
|
||||
|
||||
DCFlushRange(dst, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool Remove_001_Protection(void *Address, int Size)
|
||||
bool Remove_001_Protection(void *Address, int Size)
|
||||
{
|
||||
static const u8 SearchPattern[] = {0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
||||
static const u8 PatchData[] = {0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18};
|
||||
|
@ -5,6 +5,6 @@
|
||||
typedef void (*entry_point)(void);
|
||||
|
||||
/* Prototypes */
|
||||
s32 Apploader_Run(entry_point *, u8, GXRModeObj *vmode, bool, bool, u8, int);
|
||||
s32 Apploader_Run(entry_point *entry,u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
||||
|
||||
#endif
|
||||
|
@ -40,8 +40,8 @@ static u8 *diskid = (u8 *)0x80000000;
|
||||
GXRModeObj *disc_vmode = NULL;
|
||||
GXRModeObj *vmode = NULL;
|
||||
u32 vmode_reg = 0;
|
||||
u8 vidmode_selected = 0;
|
||||
|
||||
static u8 Tmd_Buffer[0x49e4] ALIGNED(32);
|
||||
extern void __exception_closeall();
|
||||
|
||||
entry_point p_entry;
|
||||
@ -63,9 +63,6 @@ void __Disc_SetLowMem()
|
||||
|
||||
/* Copy disc ID */
|
||||
memcpy((void *) Online_Check, (void *) Disc_ID, 4);
|
||||
|
||||
/* Flush cache */
|
||||
DCFlushRange((void *)0x80000000, 0x3F00);
|
||||
}
|
||||
|
||||
GXRModeObj * __Disc_SelectVMode(u8 videoselected, u64 chantitle)
|
||||
@ -360,9 +357,6 @@ s32 Disc_IsGC(void)
|
||||
|
||||
s32 Disc_BootPartition()
|
||||
{
|
||||
if (hooktype != 0)
|
||||
ocarina_do_code();
|
||||
|
||||
/* Set time */
|
||||
__Disc_SetTime();
|
||||
|
||||
@ -410,7 +404,7 @@ s32 Disc_BootPartition()
|
||||
|
||||
void RunApploader(u64 offset, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
||||
{
|
||||
WDVD_OpenPartition(offset, 0, 0, 0, Tmd_Buffer);
|
||||
WDVD_OpenPartition(offset);
|
||||
|
||||
/* Setup low memory */;
|
||||
__Disc_SetLowMem();
|
||||
|
@ -169,9 +169,14 @@ s32 WDVD_Eject(void)
|
||||
return (ret == 1) ? 0 : -ret;
|
||||
}
|
||||
|
||||
s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int Cert_Len, void* Out)
|
||||
s32 WDVD_OpenPartition(u64 offset)
|
||||
{
|
||||
if (di_fd < 0)
|
||||
return di_fd;
|
||||
|
||||
static u8 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32);
|
||||
static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32);
|
||||
s32 ret;
|
||||
|
||||
memset(inbuf, 0, sizeof inbuf);
|
||||
memset(outbuf, 0, sizeof outbuf);
|
||||
@ -181,17 +186,19 @@ s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int
|
||||
|
||||
Vectors[0].data = inbuf;
|
||||
Vectors[0].len = 0x20;
|
||||
Vectors[1].data = (Ticket == NULL) ? 0 : Ticket;
|
||||
Vectors[1].len = (Ticket == NULL) ? 0 : 0x2a4;
|
||||
Vectors[2].data = (Certificate == NULL) ? 0 : Certificate;
|
||||
Vectors[2].len = (Certificate == NULL) ? 0 : Cert_Len;
|
||||
Vectors[3].data = Out;
|
||||
Vectors[1].data = 0;
|
||||
Vectors[1].len = 0;
|
||||
Vectors[2].data = 0;
|
||||
Vectors[2].len = 0;
|
||||
Vectors[3].data = Tmd_Buffer;
|
||||
Vectors[3].len = 0x49e4;
|
||||
Vectors[4].data = outbuf;
|
||||
Vectors[4].len = 0x20;
|
||||
|
||||
s32 ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, Vectors);
|
||||
if (ret < 0) return ret;
|
||||
ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return (ret == 1) ? 0 : -ret;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ s32 WDVD_Seek(u64);
|
||||
s32 WDVD_Offset(u64);
|
||||
s32 WDVD_StopLaser(void);
|
||||
s32 WDVD_StopMotor(void);
|
||||
s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int Cert_Len, void* Out);
|
||||
s32 WDVD_OpenPartition(u64 offset);
|
||||
s32 WDVD_ClosePartition(void);
|
||||
s32 WDVD_UnencryptedRead(void *, u32, u64);
|
||||
s32 WDVD_Read(void *, u32, u64);
|
||||
|
@ -4,15 +4,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "mem2.hpp"
|
||||
#include "utils.h" //SAFE_CLOSE
|
||||
#include "gecko.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 offset;
|
||||
u32 srcaddress;
|
||||
u32 dstaddress;
|
||||
} WIP_Code;
|
||||
#include "wip.h"
|
||||
|
||||
static WIP_Code * CodeList = NULL;
|
||||
static u32 CodesCount = 0;
|
||||
@ -50,7 +43,7 @@ void do_wip_code(u8 * dst, u32 len)
|
||||
}
|
||||
else
|
||||
{
|
||||
gprintf("WIP: %08X Address does not match with WIP entrie.\n", CodeList[i].offset+n);
|
||||
gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n);
|
||||
gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]);
|
||||
}
|
||||
}
|
||||
@ -59,6 +52,22 @@ void do_wip_code(u8 * dst, u32 len)
|
||||
Counter++;
|
||||
}
|
||||
|
||||
//! for internal patches only
|
||||
//! .wip files override internal patches
|
||||
//! the codelist has to be freed if the set fails
|
||||
//! if set was successful the codelist will be freed when it's done
|
||||
bool set_wip_list(WIP_Code * list, int size)
|
||||
{
|
||||
if (!CodeList && size > 0)
|
||||
{
|
||||
CodeList = list;
|
||||
CodesCount = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void wip_reset_counter()
|
||||
{
|
||||
ProcessedLength = 0;
|
||||
|
@ -5,10 +5,18 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 offset;
|
||||
u32 srcaddress;
|
||||
u32 dstaddress;
|
||||
} WIP_Code;
|
||||
|
||||
bool set_wip_list(WIP_Code *list, int size);
|
||||
void wip_reset_counter();
|
||||
void free_wip();
|
||||
void do_wip_code(u8 * dst, u32 len);
|
||||
void load_wip_patches(u8 *wippath, u8 *discid);
|
||||
void do_wip_code(u8 *dst, u32 len);
|
||||
int load_wip_patches(u8 *dir, u8 *gameid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1293,7 +1293,6 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
if(currentPartition == 0)
|
||||
SDHC_Init();
|
||||
|
||||
gprintf("Booting game\n");
|
||||
usleep(100 * 1000);
|
||||
|
||||
/* Find game partition offset */
|
||||
@ -1305,7 +1304,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
RunApploader(offset, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio);
|
||||
DeviceHandler::DestroyInstance();
|
||||
USBStorage_Deinit();
|
||||
free_wip();
|
||||
gprintf("Booting game\n");
|
||||
Disc_BootPartition();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user